Java Jackson JSON库:如何实例化包含抽象字段的类

Java Jackson JSON库:如何实例化包含抽象字段的类,java,json,jackson,deserialization,Java,Json,Jackson,Deserialization,我想将一个JSON字符串转换成java对象,但是这个对象的类包含抽象字段,Jackson不能实例化这些字段,也不能生成对象。关于抽象类的默认实现,最简单的方法是什么 setDefault(AbstractAnimal.class, Cat.class); 或者根据JSON属性名决定实现类,例如,对于JSON对象: { ... cat: {...} ... } 我只想: setImpl("cat", Cat.class); 我知道在Jackson中可以在JSON中嵌

我想将一个JSON字符串转换成java对象,但是这个对象的类包含抽象字段,Jackson不能实例化这些字段,也不能生成对象。关于抽象类的默认实现,最简单的方法是什么

setDefault(AbstractAnimal.class, Cat.class);
或者根据JSON属性名决定实现类,例如,对于JSON对象:

{
    ...
    cat: {...}
    ...
}
我只想:

setImpl("cat", Cat.class);

我知道在Jackson中可以在JSON中嵌入类信息,但我不想使我使用的JSON格式复杂化。我想通过设置默认的实现类,或者通过属性名('cat')来决定使用哪个类—就像在XStream库中一样,您可以在其中编写:

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

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

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

@JsonDeserialize(as=Cat.class)
public abstract class AbstractAnimal { ... }
至于基于属性的决定,最好使用
@JsonTypeInfo
,它会自动嵌入(写入时)和使用类型信息


有多种类型的类型信息(类名、逻辑类型名)以及包含机制(包括属性、包装器数组和包装器对象)。本页:解释一些概念。

这里有一个完整的答案和一个非常清晰的例子:

Jackson将此称为多态反序列化

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


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

这个问题可以通过在抽象类上使用注释@jsondeselliate来解决 指问题和解决方案

如果您既不想用额外的字段污染JSON,也不想用注释污染类,那么可以编写一个非常简单的模块和反序列化程序,使用您想要的默认子类。由于一些样板代码,它不止一行,但仍然相对简单

class AnimalDeserializer extends StdDeserializer<Animal> {
    public AnimalDeserializer() {
        super(Animal.class);
    }

    public Animal deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException {
        return jsonParser.readValueAs(Cat.class);
    }
}

class AnimalModule extends SimpleModule {
    {
        addDeserializer(Animal.class, new AnimalDeserializer());
    }
}

Java中没有“抽象字段”这样的东西。我的意思是:
class C{Animal Animal;}
我想实例化C,其中Aniaml是抽象的,我想在这个字段中放一个Cat,它扩展了Animal,这也没有问题。没有禁止抽象类型变量的规则。可以在JSON中嵌入类信息:
@JsonTypeInfo(use=JsonTypeInfo.Id.class,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”)
。请参见注释处的注释也非常不灵活,因为我无法动态决定使用什么实现。Wrt修改类,这就是Jackson mix in注释的用途。但正确的是,此注释仅用于只有一种实现类型的情况。Jackson 1.8将具有允许简单抽象类型->impl类型映射的功能,这是值得的。mix-in注释完成了这项工作,感谢您指向正确的方向这只允许指定一个类?当有10个链接时会发生什么?链接的wiki已关闭-新的URL似乎对此表示感谢。救了我一天。我有多个抽象类的实现,所以我必须在自定义反序列化器中放置一个开关大小写。
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new AnimalModule());
return objectMapper.readValue(json, Zoo.class);