杰克逊反序列化的类型与不同的对象

Ome*_*ron 9 java jackson deserialization

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

布尔结果:

{
    id: 24428,
    rated: false
}
Run Code Online (Sandbox Code Playgroud)

地图结果:

{
    id: 78,
    rated: {
        value: 10
    }
}
Run Code Online (Sandbox Code Playgroud)

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

基本上我想把它映射到类,如:

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

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


编辑
更新的代码部分:

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Sta*_*Man 16

不不不.您不必编写自定义反序列化程序.首先使用"无类型"映射:

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);
Run Code Online (Sandbox Code Playgroud)

给出"额定"的价值Boolean或java.util.Map"给予"的价值(第一种方法); 或者JsonNode在第二种情况下.

从那里,您既可以按原样访问数据,也可以更有趣地转换为实际值:

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)
Run Code Online (Sandbox Code Playgroud)

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