3
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() 本身,我看不到任何地方可以控制创建的对象类。

4

3 回答 3

7

从谷歌到这里,找到了解决方案。实际上这些天它可能由于 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();
    }

}

有趣的文章:

杰克逊朋友的多态性

相关堆栈溢出问题

于 2017-04-25T12:03:43.263 回答
1

尚不支持此功能。

功能增强请求:http: //jira.codehaus.org/browse/JACKSON-275

有关该问题的更多详细信息:http: //jackson-users.ning.com/forum/topics/how-to-use-a-property-of?commentId= 5286555%3AComment%3A2679

于 2011-01-03T02:13:19.577 回答
1

正确 - 尚不支持使用“外部类型标识符”(不包含在要反序列化的 Object 中,但作为兄弟的标识符)。

这可以实现(例如,没有任何基本因素阻止添加支持)——除了提到的 Jira 问题可能有帮助之外,可以提交一个新功能请求以直接请求使用此类类型标识符的能力。这实际上已被多个用户提到;可能是因为存在使用这种类型结构的数据格式(geoJSON?)。

于 2011-01-04T18:23:57.590 回答