无法将JSON数据解析为POJO

无法将JSON数据解析为POJO,json,pojo,Json,Pojo,我有以下结构的JSON数据。我尝试过用相同的结构和名称创建POJO。我使用了一个DTO,它包含一个列表(在下面的JSON中,DTO具有数字对象的结构)和一个字符串“Notice”。我无法获取DTO中的数据 { "notice": "This API is in a pre-launch state, and will go through significant changes.", "1": { "next_renewal_date": "2014-08-01"

我有以下结构的JSON数据。我尝试过用相同的结构和名称创建POJO。我使用了一个DTO,它包含一个列表(在下面的JSON中,DTO具有数字对象的结构)和一个字符串“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:


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

结构应如下所示:

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

我找到了一条路。谢谢你的帮助。 我已使用以下方法将JSON转换为Hashmap: Map data=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;
    }

}

即使已经设置了正确的类型,最终的
dto
也将按照您的意愿正确序列化。

显示您的POJO以及您用于解析json的任何内容。Gson Gson=new Gson();RenewalAPICallListDTO respDto=gson.fromJson(response1.toString(),RenewalAPICallListDTO.class);public类RenewalAPICallListDTO{private Map apiCallList;public Map getApiCallList(){return apiCallList;}public void setApiCallList(Map apiCallList){this.apiCallList=apiCallList;}private String notice;public String getNotice(){return notice;}public void setNotice(String notice){this.notice=notice;}}编辑您的答案并添加正确格式的信息。JSONCallDto在JSON数据中有编号对象的进一步结构是的,这应该解决了问题,但我不能更改JSON。
{
    "notice": "random string",
    "apiCallList": {
        "1": {
            "next_renewal_date": "2014-08-01",
             ...
        },
        "2": {
            "next_renewal_date": "2014-08-01",
             ....
        }
    }
}
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);
}