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

Question

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.


Show source
| java   | android   | json   | jackson   | retrofit2   2017-01-04 12:01 4 Answers

Answers to Deserializing json from retrofit using jackson where same variable name can represent two different objects ( 4 )

  1. 2017-01-04 12:01

    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
    }
    
  2. 2017-01-04 12:01

    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
    }
    
  3. 2017-01-04 13:01

    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, e.g

     mapper.convertValue(map, Response1.class)
    
  4. 2017-01-04 21:01

    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.

Leave a reply to - Deserializing json from retrofit using jackson where same variable name can represent two different objects

◀ Go back