Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY无法正常工作

Gau*_*rav 24 polymorphism json jackson

我正在使用Jackson来解析我无法控制的JSON.JSON看起来像这样:

{
    "status":"0"
    "type":"type1"
    "info": {
       // additional fields
    }
}
Run Code Online (Sandbox Code Playgroud)

我的班级看起来像这样

public class Response {
    private String status;
    private String type;
    private Info info
}
Run Code Online (Sandbox Code Playgroud)

我使用的Info的子类取决于type属性,所以我对info的映射是

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value = Type1Info.class, name = "type1"),
        @JsonSubTypes.Type(value = Type2Info.class, name = "type2") })
public abstract class Info {
    // some fields
}
Run Code Online (Sandbox Code Playgroud)

据我所知,当区别元素与必须被转换的元素处于同一级别时,这是使用类型信息的正确方法.但这不起作用,我总是得到同样的错误:

com.fasterxml.jackson.databind.JsonMappingException:意外的标记(END_OBJECT),期望的FIELD_NAME:缺少属性'type',包含类型id

如果我将EXTERNAL_PROPERTY更改为PROPERTY,我仍会得到相同的错误.我对EXTERNAL_PROPERTY的理解是错误的吗?

Mic*_*ber 29

来自Javadoc:

类似于PROPERTY的包含机制,除了属性在层次结构中包含更高级别,即作为与要键入的JSON对象相同级别的同级属性.请注意,此选择只能用于属性,而不能用于类型(类).尝试将其用于类将导致基本PROPERTY的包含策略.

注意到can only be used for properties是粗体.来源:JsonTypeInfo.As.EXTERNAL_PROPERTY.

因此,您必须将所有注释从Info类移动到类中的属性infosetInfo方法Response.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes(value = { @JsonSubTypes.Type(value = Type1Info.class, name = "type1"),
        @JsonSubTypes.Type(value = Type2Info.class, name = "type2") })
public void setInfo(Info info) {
    this.info = info;
}
Run Code Online (Sandbox Code Playgroud)

对我来说,你也应该typeResponse课堂上删除财产.它将在序列化过程中动态生成.在反序列化中你不需要它,因为杰克逊关心类型.你的课可能如下:

class Response {

    private String status;
    private Info info;

    //getters, setters
}
Run Code Online (Sandbox Code Playgroud)

另见这个问题:JSON嵌套类数据绑定.

  • 谢谢你!你在那里救了我。实际上,我多次阅读了“只能用于属性”的部分,但没有将其链接到这意味着我必须将注释移至属性级别。 (2认同)
  • 谢谢你!就我而言,删除多余的属性“type”有帮助 (2认同)