简体   繁体   English

使用jackson从改造中反序列化json,其中相同的变量名称可以表示两个不同的对象

[英]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) 改造2的反应可能是以下类型。(我们事先不知道哪种反应会来)

{
    "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. 有没有办法定义一个类,以便反序列化杰克逊将检查对象类型“driverId”包含并指定它在类中说“driverIdObj”字段或“driverIdStr”字段。

You could deserialize to a Map. 您可以反序列化为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 看一下这个答案: 根据对象类型反序列化JSON

To convert from Map to Object you can use ObjectMapper::convertValue, eg 要从Map转换为Object,您可以使用ObjectMapper :: convertValue,例如

 mapper.convertValue(map, Response1.class)

You can check whether the json has values inside it; 你可以检查json里面是否有值;

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. 使用JsonNode类对响应类中的driverId字段进行一些特殊处理。 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. 这使您可以维持大多数响应的正常方法,同时可以轻松处理特殊字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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