我有以下课程:
public class City
{
Zoo zoo;
}
public class Zoo
{
Animal[] animals;
}
public abstract class Animal
{
String name;
abstract void eat();
}
我想用Jackson反序列化City
类的实例。但是,由于Animal
是一个抽象类型,我有以下例外:
无法读取JSON:无法构造Animal的实例,问题: 抽象类型要么需要映射到具体类型,要有自定义 反序列化器,或者使用其他类型信息进行实例化
如何将Animal
映射到具体类型?
问题在于我能够修改仅 City
类。
答案 0 :(得分:2)
由于您只能修改City
课程,因此您可能会发现mix-in annotations有用。我们的想法是创建并注释一个新类,它可以作为您希望可以注释的类的代理(但无论出于何种原因都可以)。然后你向杰克逊注册你的代理人,告诉它寻找你的代理人而不是实际的班级的注释。
首先,您可以尝试为Animal
创建混合,并使用@JsonDeserialize(as=ConcreteClass.class)
注释混合类,如Vince Emigh建议的那样。一旦您完成了这项工作,您可以尝试使用polymorphic type handling注释进行注释。
答案 1 :(得分:2)
对于一对一(抽象/ impl)用例,注册子类(可以通过ObjectMapper.registerSubtypes(...)
或使用SimpleModule
进行注册)是注释的替代方法。
但是如果你有真正的多态类型,那么@JsonTypeInfo
注释就是关键。它需要添加到使用静态类型的基类(如Animal
)中,并且会在序列化时添加类型标识符,并在反序列化时使用该ID。
对于类型id(类名与逻辑名)的种类以及包含样式(作为属性,作为包装器数组,作为包装器对象,作为外部属性),有多种选择。