Jackson 反序列化不同对象的类型 [英] Jackson deserialization of type with different objects

查看:28
本文介绍了Jackson 反序列化不同对象的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个返回布尔值或单例映射的网络服务的结果,例如

I have a result from a web service that returns either a boolean value or a singleton map, e.g.

布尔结果:

{
    id: 24428,
    rated: false
}

地图结果:

{
    id: 78,
    rated: {
        value: 10
    }
}

个人而言,我可以轻松地映射这两者,但我一般如何做?

Individually I can map both of these easily, but how do I do it generically?

基本上我想将它映射到一个类:

Basically I want to map it to a class like:

public class Rating {
    private int id;
    private int rated;
    ...
    public void setRated(?) {
        // if value == false, set rated = -1;
        // else decode "value" as rated
    }
}

所有多态示例都使用 @JsonTypeInfo 根据数据中的属性进行映射,但在这种情况下我没有该选项.

All of the polymorphic examples use @JsonTypeInfo to map based on a property in the data, but I don't have that option in this case.

<小时>编辑
更新后的代码部分:


EDIT
The updated section of code:

@JsonProperty("rated")
public void setRating(JsonNode ratedNode) {
    JsonNode valueNode = ratedNode.get("value");
    // if the node doesn't exist then it's the boolean value
    if (valueNode == null) {
        // Use a default value
        this.rating = -1;
    } else {
        // Convert the value to an integer
        this.rating = valueNode.asInt();
    }
}

推荐答案

不不不.您不必编写自定义解串器.只需先使用无类型"映射:

No no no. You do NOT have to write a custom deserializer. Just use "untyped" mapping first:

public class Response {
  public long id;
  public Object rated;
}
// OR
public class Response {
  public long id;
  public JsonNode rated;
}
Response r = mapper.readValue(source, Response.class);

为评级"提供 Booleanjava.util.Map 的值(第一种方法);或 JsonNode 第二种情况.

which gives value of Boolean or java.util.Map for "rated" (with first approach); or a JsonNode in second case.

由此,您可以按原样访问数据,或者更有趣的是,转换为实际值:

From that, you can either access data as is, or, perhaps more interestingly, convert to actual value:

if (r.rated instanced Boolean) {
    // handle that
} else {
    ActualRated actual = mapper.convertValue(r.rated, ActualRated.class);
}
// or, if you used JsonNode, use "mapper.treeToValue(ActualRated.class)

还有其他类型的方法——使用创建者ActualRated(boolean)",让实例从 POJO 构建,从标量构建.但我认为以上应该有效.

There are other kinds of approaches too -- using creator "ActualRated(boolean)", to let instance constructed either from POJO, or from scalar. But I think above should work.

这篇关于Jackson 反序列化不同对象的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆