如何使用杰克逊的嵌套抽象字段实例化类?

时间:2015-05-17 16:40:46

标签: java json jackson abstract

我有以下课程:

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类。

2 个答案:

答案 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(类名与逻辑名)的种类以及包含样式(作为属性,作为包装器数组,作为包装器对象,作为外部属性),有多种选择。