0

I am getting nested json object and json array as response while making ReST call. Nested json array and json object comes randomly. It may not be present as part of response everytime. I want to deserialize json in such a way that all the fields in json place at the root level of java object.

JSON Response

{
    "data": {
        "id":"42342sdz",
        "details" : {
            "username": "Username",
            "location": "Location",
            "history":[
                { 
                    "historyId":"34312cs", "historyDetail":"Some val", "datetime":"Some val", 
                    "myObj":{
                        "myField" : "Some val"
                    }
                },
                { "historyId":"34312cs", "historyDetail":"Some val", "datetime":"Some val"}
            ]
        }
    }
}

Java Object which I want to build by parsing above JSON response.

class ResponseObject {
String id;
String username;
String location;
List<History> historyList;
//Getters and Setters
}

class History {
String historyId;
String historyDetails
String datetime;
String myField;
//Getters and Setters
}
Harsh Kanakhara
  • 909
  • 4
  • 13
  • 38

1 Answers1

0

I'm not really sure what you mean when you say that the JSON object comes randomly. If you mean that the fields themselves are random (with random labels), then I'm not confident that you can store them as fields in a Java object like that. However, if you know the fields beforehand, then you can tell Jackson (the JSON deserializer that Spring Boot uses) how to deserialize the object by adding a method into your ResponseObject class that looks like this:

@SuppressWarnings("unchecked")
@JsonProperty("data")
private void unpackNested(Map<String, Object> data) {
    this.id = (String) data.get("id");
    Map<String, Object> details = (Map<String, Object>) data.get("details");
    this.username = (String) details.get("username");
    this.location = (String) details.get("location");
    List<Map<String, Object>> originalHistory = (List<Map<String, Object>>) details.get("history");
    historyList = new ArrayList<>();
    if (originalHistory != null) {
        for (Map<String, Object> h : originalHistory) {
            History history = new History();
            history.setHistoryId((String) h.get("historyId"));
            history.setHistoryDetails((String) h.get("historyDetail"));
            history.setDatetime((String) h.get("datetime"));
            Map<String, Object> myObj = (Map<String, Object>) h.get("myObj");
            if (myObj != null) {
                history.setMyField((String) myObj.get("myField"));
            }
            historyList.add(history);
        }
    }
}

If you don't know the names of the fields, then I think the best you can do is store it into a flat Map<String, Object>.