java - 反序列化时使用父对象的属性来确定子类?

标签 java json polymorphism jackson

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();
    }

}

有趣的文章:

Polymorphism with jackson friend

Related stack overflow question

关于java - 反序列化时使用父对象的属性来确定子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4574952/

相关文章:

java - JAXB 编码到 HTML 在 xsl :when using <a> tag 中引发异常

json - POST 请求负载的内容类型

javascript - 更新 AngularJS 中数组的数据

c++ - 什么时候使用虚拟析构函数?

c++ - 为什么多态性在没有指针/引用的情况下不起作用?

java - 在 Ice Cream Sandwich 中移动 Android 状态栏

java - 数据结构 : Checking if a record exists in a database?

c++ - 如果仅部分重载重载函数,多态性将不起作用

java - 绘制透明路径

javascript - 使用 $.ajax 在 PHP 中获取空数组