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

Posted

技术标签:

【中文标题】使用jackson从改造中反序列化json,其中相同的变量名可以代表两个不同的对象【英文标题】:Deserializing json from retrofit using jackson where same variable name can represent two different objects 【发布时间】:2017-05-18 15:51:34 【问题描述】:

retrofit2 的响应可能有以下几种类型。(我们事先不知道会出现哪种响应)


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


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

有什么方法可以定义一个类,以便在反序列化杰克逊时检查对象“driverId”包含的类型并将其分配给类中的“driverIdObj”字段或“driverIdStr”字段。

【问题讨论】:

您必须为密钥 driverId 编写自己的反序列化方案。 Dharmendra 你能提供一些链接或提示一些代码,这可能对我有帮助吗? 【参考方案1】:

您可以反序列化为 Map。之后,您可以检查地图并决定将地图转换为两种类型中的哪一种。看看这个答案:Deserializing JSON based on object type

要从 Map 转换为 Object,您可以使用 ObjectMapper::convertValue,例如

 mapper.convertValue(map, Response1.class)

【讨论】:

【参考方案2】:

你可以检查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

【讨论】:

【参考方案3】:

试试这个

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

【讨论】:

但是由于我使用的是带有改造 2 的 Jackson,如果可以通过可能在 Jackson Deserializer 或其他地方进行一些调整来完成这将是有帮助的。这是一种非常基本的方式。【参考方案4】:

使用JsonNode 类对响应类中的driverId 字段进行一些特殊处理。类似于以下内容:

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

这使您可以在大部分响应中保持正常的方法,同时可以以最小的痛苦处理特殊领域。

【讨论】:

以上是关于使用jackson从改造中反序列化json,其中相同的变量名可以代表两个不同的对象的主要内容,如果未能解决你的问题,请参考以下文章

Jackson 错误:无法从 START_ARRAY 令牌中反序列化 `java.lang.String` 的实例

com.fasterxml.jackson.databind.exc.MismatchedInputException:无法从START_ARRAY令牌中反序列化Object的实例

理解异常的麻烦:“无法从 START_OBJECT 令牌中反序列化 `java.lang.String` 的实例”在 Jackson 中使用 ObjectMapper

com.fasterxml.jackson.databind.exc.MismatchedInputException:无法从 START_OBJECT 令牌中反序列化 `java.util.Arra

如何使用jackson(Java)反序列化对象中的json对象?

Jackson 在 Spring Boot 中反序列化 GeoJson Point