0

I have JSON data with following structure. I have tried creating POJOs with same structure and with same names. I have taken a DTO which contains a list (of DTOs with structure of the numeral objects in the following JSON) and a String "Notice". I am not able to get the data in the 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;
    }
}

Method call:

Gson gson = new Gson();
RenewalAPICallListDTO respDto = gson.fromJson(response1.toString(), RenewalAPICallListDTO.class);
Ren
  • 2,852
  • 2
  • 23
  • 45

3 Answers3

0

The json and POJO do not match. The attribute apiCallList is missing in your JSON string.

The structure should be like:

{
    "notice": "random string",
    "apiCallList": {
        "1": {
            "next_renewal_date": "2014-08-01",
             ...
        },
        "2": {
            "next_renewal_date": "2014-08-01",
             ....
        }
    }
}
Rima
  • 545
  • 6
  • 12
0

I have found a way. Thanks for the help. I have converted the JSON into Hashmap using : Map data = mapper.readValue(json,Map.class); and then iterated the map, using the objects to populate POJOs.

0

What you are looking for can be achieve with Jackson with a custom deserializer, as the following:

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;
    }

}

Usage:

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);
} 

The final dto will be correctly serialized like you want, even with the correct types already set.

dambros
  • 4,252
  • 1
  • 23
  • 39