简体   繁体   中英

Deserializing json from retrofit using jackson where same variable name can represent two different objects

The response from retrofit2 may be of the following types.(and we don't know before hand which response will come)

{
    "id": "abc",
    "place": "LA",
    "driverId": "abbabaaan"
}

or

{
    "id": "abc",
    "place": "LA",
    "driverId": {
        "name": "xyz",
        "id": "jygsdsah",
        "car": "merc"
    }
}

Is there any way to define a class so that while deserializing jackson will check the type of object "driverId" contains and assigns it to say "driverIdObj" field or "driverIdStr" field in the class.

You could deserialize to a Map. Afterwards, you could inspect the map and decide to which of the 2 types you convert the map. Take a look at this answer: Deserializing JSON based on object type

To convert from Map to Object you can use ObjectMapper::convertValue, eg

 mapper.convertValue(map, Response1.class)

You can check whether the json has values inside it;

String jsonString= "{ ... }";
Object json = new JSONTokener(jsonString).nextValue();
 if (json instanceof JSONObject){ 
   //do operations related with object
 }
else if (json instanceof JSONArray) {
 //do operations based on an array
}

Try this

JSONObject jsonObject = new JSONObject("your Response String");
Object obj = jsonObject.get("driverId");    //handle Exceptions
if (obj instanceof String){ 
   //do String stuff
}
else if (obj instanceof JSONObject) {
   //do json object stuff
}

Make some special handling for the driverId field in your response class using the JsonNode class. Something like the following:

public class Response {
    private String id, place, driverIdStr;
    private DriverIdObj driverIdObj;

    // ... Various getters and setters omitted.

    public void setDriverId(JsonNode driverId) {
        if (driverId.isObject()) {
            // Process the complex version of DriverId.
            driverIdObj = new DriverIdObj( /* retrieve fields from JsonNode */ );
        } else {
            // Process the simple version of DriverId
            driverIdStr = driverId.asText();
        }
    }
}

This lets you maintain a normal approach for most of the response, while making it possible to handle the special field with a minimum of pain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM