无法将 JSON 数据解析为 POJO
Not able to Parse JSON data to POJO
我有 JSON 具有以下结构的数据。我尝试创建具有相同结构和相同名称的 POJO。我采用了一个 DTO,其中包含一个列表(具有以下数字对象结构的 DTO JSON)和一个字符串 "Notice"。我无法获取 DTO 中的数据。
{
"notice": "This API is in a pre-launch state, and will go through significant changes.",
"1": {
"next_renewal_date": "2014-08-01",
"next_renewal_fee": {
"price": "800.0",
"currency": "USD"
},
"next_renewal_description": "1st Annuity - Official Fee",
"next_per_claim_fee": {
"price": "0.0",
"currency": "USD",
"free_claims": 0,
"claim_type": "claims_count"
},
"next_agent_fee": {
"price": "0.0",
"currency": "USD"
},
"grace_period_end_date": "2015-02-01"
},
"2": {
"next_renewal_date": "2018-08-01",
"next_renewal_fee": {
"price": "1800.0",
"currency": "USD"
},
"next_renewal_description": "2nd Annuity - Official Fee",
"next_per_claim_fee": {
"price": "0.0",
"currency": "USD",
"free_claims": 0,
"claim_type": "claims_count"
},
"next_agent_fee": {
"price": "0.0",
"currency": "USD"
},
"grace_period_end_date": "2019-02-01"
}
}
POJO:
public class RenewalAPICallListDTO {
private Map<Integer,JSONCallDto> apiCallList;
public Map<Integer, JSONCallDto> getApiCallList() {
return apiCallList;
}
public void setApiCallList(Map<Integer, JSONCallDto> apiCallList) {
this.apiCallList = apiCallList;
}
private String notice;
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
}
方法调用:
Gson gson = new Gson();
RenewalAPICallListDTO respDto = gson.fromJson(response1.toString(), RenewalAPICallListDTO.class);
json 和 POJO 不匹配。 JSON 字符串中缺少属性 apiCallList
。
结构应该是这样的:
{
"notice": "random string",
"apiCallList": {
"1": {
"next_renewal_date": "2014-08-01",
...
},
"2": {
"next_renewal_date": "2014-08-01",
....
}
}
}
我找到方法了。谢谢您的帮助。
我已经使用以下方法将 JSON 转换为 Hashmap:
地图数据=mapper.readValue(json,Map.class);
然后迭代映射,使用对象填充 POJO。
你要找的东西可以用带有自定义反序列化器的 Jackson 来实现,如下所示:
public class CustomDeserializer extends JsonDeserializer<RenewalAPICallListDTO> {
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
public RenewalAPICallListDTO deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
Iterator<Entry<String, JsonNode>> nodeIterator = node.fields();
RenewalAPICallListDTO dto = new RenewalAPICallListDTO();
Map<Integer, JsonCallDto> map = new HashMap<>();
while (nodeIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = nodeIterator.next();
if (entry.getKey().equalsIgnoreCase("notice")) {
dto.setNotice(entry.getValue().toString());
} else {
map.put(Integer.parseInt(entry.getKey()), mapper.readValue(entry.getValue().toString(), JsonCallDto.class));
}
}
dto.setApiCallList(map);
return dto;
}
}
用法:
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(RenewalAPICallListDTO.class, new CustomDeserializer());
mapper.registerModule(module);
RenewalAPICallListDTO dto = mapper.readValue(JSON, RenewalAPICallListDTO.class);
}
最终的 dto
将按照您的要求正确序列化,即使已经设置了正确的类型。
我有 JSON 具有以下结构的数据。我尝试创建具有相同结构和相同名称的 POJO。我采用了一个 DTO,其中包含一个列表(具有以下数字对象结构的 DTO JSON)和一个字符串 "Notice"。我无法获取 DTO 中的数据。
{
"notice": "This API is in a pre-launch state, and will go through significant changes.",
"1": {
"next_renewal_date": "2014-08-01",
"next_renewal_fee": {
"price": "800.0",
"currency": "USD"
},
"next_renewal_description": "1st Annuity - Official Fee",
"next_per_claim_fee": {
"price": "0.0",
"currency": "USD",
"free_claims": 0,
"claim_type": "claims_count"
},
"next_agent_fee": {
"price": "0.0",
"currency": "USD"
},
"grace_period_end_date": "2015-02-01"
},
"2": {
"next_renewal_date": "2018-08-01",
"next_renewal_fee": {
"price": "1800.0",
"currency": "USD"
},
"next_renewal_description": "2nd Annuity - Official Fee",
"next_per_claim_fee": {
"price": "0.0",
"currency": "USD",
"free_claims": 0,
"claim_type": "claims_count"
},
"next_agent_fee": {
"price": "0.0",
"currency": "USD"
},
"grace_period_end_date": "2019-02-01"
}
}
POJO:
public class RenewalAPICallListDTO {
private Map<Integer,JSONCallDto> apiCallList;
public Map<Integer, JSONCallDto> getApiCallList() {
return apiCallList;
}
public void setApiCallList(Map<Integer, JSONCallDto> apiCallList) {
this.apiCallList = apiCallList;
}
private String notice;
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
}
方法调用:
Gson gson = new Gson();
RenewalAPICallListDTO respDto = gson.fromJson(response1.toString(), RenewalAPICallListDTO.class);
json 和 POJO 不匹配。 JSON 字符串中缺少属性 apiCallList
。
结构应该是这样的:
{
"notice": "random string",
"apiCallList": {
"1": {
"next_renewal_date": "2014-08-01",
...
},
"2": {
"next_renewal_date": "2014-08-01",
....
}
}
}
我找到方法了。谢谢您的帮助。 我已经使用以下方法将 JSON 转换为 Hashmap: 地图数据=mapper.readValue(json,Map.class); 然后迭代映射,使用对象填充 POJO。
你要找的东西可以用带有自定义反序列化器的 Jackson 来实现,如下所示:
public class CustomDeserializer extends JsonDeserializer<RenewalAPICallListDTO> {
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
public RenewalAPICallListDTO deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
Iterator<Entry<String, JsonNode>> nodeIterator = node.fields();
RenewalAPICallListDTO dto = new RenewalAPICallListDTO();
Map<Integer, JsonCallDto> map = new HashMap<>();
while (nodeIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = nodeIterator.next();
if (entry.getKey().equalsIgnoreCase("notice")) {
dto.setNotice(entry.getValue().toString());
} else {
map.put(Integer.parseInt(entry.getKey()), mapper.readValue(entry.getValue().toString(), JsonCallDto.class));
}
}
dto.setApiCallList(map);
return dto;
}
}
用法:
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(RenewalAPICallListDTO.class, new CustomDeserializer());
mapper.registerModule(module);
RenewalAPICallListDTO dto = mapper.readValue(JSON, RenewalAPICallListDTO.class);
}
最终的 dto
将按照您的要求正确序列化,即使已经设置了正确的类型。