我使用的是Jackson 1.9.x。坚持动物的例子,以下是我想做的:
假设我有一个动物类:
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()的实现)。
我看到的问题有解决办法吗?
我也遇到了同样的问题,发现子类型映射需要唯一的类。
我所做的是创建两个扩展同一基类的类。扩展类是空的,因为它们与基类具有相同的属性。然后将它们添加到"子类型"映射中。例如,在您的情况下,它将是-
@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{}
我知道这不是最好的方法,但在问题没有解决之前,这可能是解决这个问题的最佳方法。我现在采用了这种方法。
希望它能帮助你!
该错误已在2.6.0版本中得到解决,因此您只需将Jackson更新到22.6.0
也许不是通过使用注释。问题来自这样一个事实,即这种映射不适用于序列化,并且现有的映射确实期望一对一(双射)关系。但您可能想要在jackson数据绑定问题跟踪器中提交RFE;增加支撑是可能的。
您可以引入一个中级抽象类。
您也可以避免列出整个子类型列表,而使用@JsonTypeName
这个解决方案是IMHO更ellegant,因为
- 定义紧挨着实际的子类型
- 子类型的长列表使代码的可维护性降低
- 你可以";插件";在其他地方上课
Howto
默认情况下,Jackson不会遍历类型树来查找嵌套的子类型。它将失败:
无法将类型id"Dodo"解析为
的子类型ch.zizka.test.Animal
:已知类型ids=〔com.zizka.test.Bird,…Mammal〕
在[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。(Jackson 2.10.5)
从Jackson 2.12开始,@JsonSubTypes.Type
注释中有一个单独的字段。
/**
* (optional) Logical type names used as the type identifier for the class: used if
* more than one type name should be associated with the same type.
*
* @since 2.12
*/
public String[] names() default {};
检查下面的示例代码。
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Mammal.class, names = {"Dog", "Cat"}),
@JsonSubTypes.Type(value = Bird.class, names = {"Dodo", "Cockatoo"}},
public class Animal {
}