如何用 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 映射到具体类型?

问题是我只能修改Cityclass.

由于您只能修改 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 名称与逻辑名称)以及包含样式(如 属性、作为包装器数组、作为包装器对象、作为外部 属性)都有多种选择.