14

我正在使用杰克逊 1.9.x。坚持以动物为例,这就是我想做的事情:

假设我有一个 Animal 类:

public class Animal {
    private String type;
    // accessors
}

public class Mammal extends Animal {
    private String diet;
    // accessors
}

public class Bird extends Animal {
    private boolean tropical;
    // accessors
}

我希望能够做这样的事情(我将一些子类型映射到一个类,还有一些映射到另一个类):

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Mammal.class, name = "Dog"),
                @JsonSubTypes.Type(value = Mammal.class, name = "Cat"),
                @JsonSubTypes.Type(value = Bird.class, name = "Dodo"},
                @JsonSubTypes.Type(value = Bird.class, name = "Cockatoo"})
public class Animal {

}

我现在看到的是杰克逊只会识别狗到哺乳动物和渡渡鸟到鸟的映射。这是因为 StdSubtypeResolver._collectAndResolve() 只允许同一个类注册一次(由于 NamedType.equals() 的实现)。

我看到的问题有解决方法吗?

4

4 回答 4

7

我也遇到了同样的问题,发现子类型映射需要唯一的类。

我所做的是创建两个扩展同一个基类的类。扩展类是空的,因为它们具有与基类相同的属性。然后将它们添加到子类型地图中。例如,在您的情况下,它将是 -

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Mammal.class, name = "Dog"),
            @JsonSubTypes.Type(value = Mammal.class, name = "Cat"),
            @JsonSubTypes.Type(value = BirdDodo.class, name = "Dodo"},
            @JsonSubTypes.Type(value = BirdCockatoo.class, name = "Cockatoo"})
public class Animal {

}

public class BirdCockatoo extends Cockatoo{}
public class BirdDodo extends Dodo{}

我知道这不是最好的方法,但在问题没有解决之前,它可能是解决这个问题的最佳方法。我现在遵循这种方法。

希望对你有帮助!

于 2016-02-05T09:57:14.460 回答
7

该错误已在2.6.0版本中得到解决,因此您只需将 Jackson 更新到2.6.0或更高版本即可。附加信息在这里这里

于 2016-04-28T00:49:04.240 回答
4

也许不是通过使用注释。问题来自这样一个事实,即这种映射不适用于序列化,并且现有映射确实期望一对一(双射)关系。但是您可能想在jackson-databind issue tracker提交 RFE ;增加支持是可能的。

于 2013-08-23T20:34:01.917 回答
1

您可能会引入一个中级抽象类。

您也可以避免列出子类型的整个列表并使用@JsonTypeName.
恕我直言,这个解决方案更优雅,因为

  • 定义就在实际子类型旁边,
  • 子类型的长列表使代码的可维护性降低,
  • 您可以在其他地方“插入”类。

如何

默认情况下,Jackson 不会遍历类型树来查找嵌套子类型。它会失败:

无法将类型 id 'Dodo' 解析为以下类型的子类型
ch.zizka.test.Animal:已知类型 ids = [com.zizka.test.Bird, ... Mammal] ...
at [Source: (byte[])"{

您需要添加@JsonSubTypes到中级类 ( Bird, Mammal)。

结果

  • Animal@JsonTypeInfo(use=NAME)
    • Mammal@JsonSubTypes(@Type(Dog.class, Cat.class))
      • Dog@JsonTypeName("Dog")
      • Cat@JsonTypeName("Cat")
    • Bird@JsonSubTypes(@Type(Dodo.class, Cockatoo.class))
      • Dodo@JsonTypeName("Dodo")
      • Cockatoo@JsonTypeName("Cockatoo")

刚刚测试过 - #WORKSFORME。(杰克逊 2.10.5)

于 2021-01-28T01:00:11.750 回答