children: [
{
o kind: "t3"
data: { // ExampleNodeT3 class should be used for kind == t3
+ t3var1: "val1"
+ t3var2: true
}
}
{
o kind: "t4"
data: { // ExampleNodeT4 class should be used for kind == t4
+ t4var1: false
+ t4var2: 2346
}
}
] ... etc.
@JsonTypeInfo(use=Id.NAME, property="kind")
@JsonSubTypes({
@Type(value=ExampleNodeT3.class, name="t3"),
@Type(value=ExampleNodeT4.class, name="t4")})
public abstract class ExampleNode {
...
public void setData(ExampleNode data) {
this.data = data;
}
当尝试使用 Jackson 对其进行反序列化时,创建 ExampleNode 数据时 JsonTypeInfo 提示失败,因为“kind”属性与其父属性关联并且不可见。我尝试了工厂方法的各种变体和 Jackson 注释,但是因为 Jackson 创建了 ExampleNode 对象并将其传递给 setData() 本身,所以我看不出有什么地方可以控制创建的对象类。
最佳答案
从 google 到这里,找到了解决方案。实际上这些天它可能由于 include=JsonTypeInfo.As.EXTERNAL_PROPERTY ,例如:
public class Parent {
@JsonProperty("type")
public String type;
@JsonProperty("data")
@JsonInclude(Include.NON_NULL)
public ChildBase ChildBase;
public Parent() {
medias = new HashMap<>();
}
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="type")
@JsonTypeIdResolver(ChildBaseByParentTypeResolver.class)
public void setChildBase(ChildBase ChildBase){
this.ChildBase = ChildBase;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChildBase {
public String someStr;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class AggressiveChild extends ChildBase{
public String someStr1;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChilledChild extends ChildBase{
public String someStr1;
}
public class ChildBaseByParentTypeResolver extends TypeIdResolverBase {
private JavaType superType;
@Override
public void init(JavaType baseType) {
superType = baseType;
}
@Override
public Id getMechanism() {
return Id.NAME;
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
Class<?> subType = ChildBase.class;
switch (id) {
case "agressiveParent":
subType = AggressiveChild.class;
break;
case "chilledParent":
subType = ChilledChild.class;
break;
}
return context.constructSpecializedType(superType, subType);
}
@Override
public JavaType typeFromId(String directiveType) {
throw new NotImplementedException();
}
}
有趣的文章:
关于java - 反序列化时使用父对象的属性来确定子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4574952/