如何用 Jackson 的嵌套抽象字段实例化 class?
How to instantiate class with nested abstract field with Jackson?
我得到了以下 classes :
public class City
{
Zoo zoo;
}
public class Zoo
{
Animal[] animals;
}
public abstract class Animal
{
String name;
abstract void eat();
}
我想用 Jackson 反序列化 City
class 的一个实例。 Howerer,因为 Animal
是一个抽象类型,我有以下异常:
Could not read JSON: Can not construct instance of Animal, problem:
abstract types either need to be mapped to concrete types, have custom
deserializer, or be instantiated with additional type information
如何将 Animal
映射到具体类型?
问题是我只能修改City
class.
由于您只能修改 City
class,您可能会发现 mix-in annotations 很有用。这个想法是您创建并注释一个新的 class 作为您希望可以注释的 class 的代理(但由于任何原因不能)。然后你向 Jackson 注册你的代理,告诉它在你的代理上寻找注释而不是实际的 class.
首先,您可以尝试为 Animal
创建一个混音,并按照 Vince Emigh 的建议用 @JsonDeserialize(as=ConcreteClass.class)
注释混音 class。完成后,您可以尝试使用 polymorphic type handling 注释对其进行注释。
对于一对一 (abstract/impl) 用例,注册子 classes(您可以通过 ObjectMapper.registerSubtypes(...)
或使用 SimpleModule
来完成)是注释的替代方法。
但是如果你有真正的多态类型,@JsonTypeInfo
注释是关键。它需要添加到使用静态类型(如 Animal
)的基础 class 中,并且会导致在序列化时添加类型标识符,并在反序列化时使用该 id。
对于类型 ID 的种类(class 名称与逻辑名称)以及包含样式(如 属性、作为包装器数组、作为包装器对象、作为外部 属性)都有多种选择.
我得到了以下 classes :
public class City
{
Zoo zoo;
}
public class Zoo
{
Animal[] animals;
}
public abstract class Animal
{
String name;
abstract void eat();
}
我想用 Jackson 反序列化 City
class 的一个实例。 Howerer,因为 Animal
是一个抽象类型,我有以下异常:
Could not read JSON: Can not construct instance of Animal, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
如何将 Animal
映射到具体类型?
问题是我只能修改City
class.
由于您只能修改 City
class,您可能会发现 mix-in annotations 很有用。这个想法是您创建并注释一个新的 class 作为您希望可以注释的 class 的代理(但由于任何原因不能)。然后你向 Jackson 注册你的代理,告诉它在你的代理上寻找注释而不是实际的 class.
首先,您可以尝试为 Animal
创建一个混音,并按照 Vince Emigh 的建议用 @JsonDeserialize(as=ConcreteClass.class)
注释混音 class。完成后,您可以尝试使用 polymorphic type handling 注释对其进行注释。
对于一对一 (abstract/impl) 用例,注册子 classes(您可以通过 ObjectMapper.registerSubtypes(...)
或使用 SimpleModule
来完成)是注释的替代方法。
但是如果你有真正的多态类型,@JsonTypeInfo
注释是关键。它需要添加到使用静态类型(如 Animal
)的基础 class 中,并且会导致在序列化时添加类型标识符,并在反序列化时使用该 id。
对于类型 ID 的种类(class 名称与逻辑名称)以及包含样式(如 属性、作为包装器数组、作为包装器对象、作为外部 属性)都有多种选择.