无法将JSON数据解析为POJO

时间:2016-04-04 09:55:12

标签: json 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);

3 个答案:

答案 0 :(得分:0)

json和POJO不匹配。您的JSON字符串中缺少属性apiCallList

结构应该是:

{
    "notice": "random string",
    "apiCallList": {
        "1": {
            "next_renewal_date": "2014-08-01",
             ...
        },
        "2": {
            "next_renewal_date": "2014-08-01",
             ....
        }
    }
}

答案 1 :(得分:0)

我找到了办法。谢谢您的帮助。 我使用以下方法将JSON转换为Hashmap: Map data = mapper.readValue(json,Map.class); 然后迭代地图,使用对象填充POJO。

答案 2 :(得分:0)

您正在寻找的是使用自定义反序列化器的杰克逊,如下所示:

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也会按照您的需要正确序列化。