2011-03-30 58 views
24

我想将JSON字符串转换为java对象,但该对象的类包含抽象字段,Jackson无法实例化,并且不会生成目的。什么是告诉它的抽象类的一些默认实现最简单的方法,像杰克逊JSON库:如何实例化一个包含抽象字段的类

setDefault(AbstractAnimal.class, Cat.class); 

或者决定有关基于JSON的实现类属性的名称,例如。为JSON对象:

{ 
    ... 
    cat: {...} 
    ... 
} 

我只想WITE:

setImpl("cat", Cat.class); 


我知道这是可能在杰克逊嵌入内部JSON类的信息,但我不希望JSON格式复杂我使用。我想决定只是通过设置默认的实现类,或属性名称(“猫”)使用什么类 - 像XStream的图书馆,在那里你写:

xStream.alias("cat", Cat.class); 

有没有办法这样做,特别是在一行中,还是需要更多的代码?

+0

在Java中没有像'抽象字段'那样的东西。 – EJP 2011-03-30 23:15:01

+1

我的意思是: 'class C {animal animal; }' 我想实例化C,其中Aniaml是抽象的,我想在这个字段中放入一个Cat,它扩展了Animal – Marcin 2011-03-31 07:07:39

+0

,所以没有问题。对于抽象类型的变量没有规则。 – EJP 2011-04-05 10:47:59

回答

36

有多种方式; 1.8版本之前,最简单的方法可能是要做到:

@JsonDeserialize(as=Cat.class) 
public abstract class AbstractAnimal { ... } 

如在决定基于属性,这是最好的做用@JsonTypeInfo,它不自动embeddeding(写入时)和使用的类型信息。

有多种类型的信息(类名称,逻辑类型名称)以及包含机制(as-included-property,as-wrapper-array,as-wrapper-object)。本页面:https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization解释了一些概念。

+0

评论感谢您的答案! @JsonDeserialize是我的问题的理想之处,因为它不需要在JSON中嵌入任何类型的信息。但是我不能使用它,因为我不能修改我想要实例化的类,因为它们是其他项目的一部分,并且更改此代码可能会破坏其他代码。 – Marcin 2011-04-06 13:39:01

+4

注解也非常不灵活,因为我无法动态地决定我使用的实现。 – Marcin 2011-04-06 13:47:38

+1

Wrt修改类,这是杰克逊混合注释的目的。但是正确的,这个注释仅仅用于只有一种实现类型的情况。 Jackson 1.8将具有允许简单的抽象类型 - > impl类型映射的功能,以实现其价值。 – StaxMan 2011-04-08 01:09:44

2

一个非常明显的例子,一个羽翼丰满的答案可以在这里找到:https://stackoverflow.com/a/30386694/584947

杰克逊称此为多态反序列化。

它肯定帮我解决了我的问题。我有一个抽象类,我保存在数据库中,需要将它解组到一个类的具体实例(可以理解)。

它将向您展示如何正确注释父级抽象类以及如何在解组时运行时教授杰克逊如何在可用的子类候选中进行选择。