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类移动到类中的属性info或setInfo方法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)
对我来说,你也应该type从Response课堂上删除财产.它将在序列化过程中动态生成.在反序列化中你不需要它,因为杰克逊关心类型.你的课可能如下:
class Response {
private String status;
private Info info;
//getters, setters
}
Run Code Online (Sandbox Code Playgroud)
另见这个问题:JSON嵌套类数据绑定.