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

Mar*_*cin 30 java json jackson deserialization

我想将JSON字符串转换为java对象,但此对象的类包含杰克逊无法实例化的抽象字段,并且不生成该对象.告诉它关于抽象类的一些默认实现的最简单方法是什么,比如

setDefault(AbstractAnimal.class, Cat.class);
Run Code Online (Sandbox Code Playgroud)

或者根据JSON属性名称来决定实现类,例如.对于JSON对象:

{
    ...
    cat: {...}
    ...
}
Run Code Online (Sandbox Code Playgroud)

我愿意:

setImpl("cat", Cat.class);
Run Code Online (Sandbox Code Playgroud)


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

xStream.alias("cat", Cat.class);
Run Code Online (Sandbox Code Playgroud)

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

Sta*_*Man 41

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

@JsonDeserialize(as=Cat.class)
public abstract class AbstractAnimal { ... }
Run Code Online (Sandbox Code Playgroud)

至于基于属性的决定,最好使用@JsonTypeInfo,它自动嵌入(写入时)和使用类型信息.

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

  • 注释也非常不灵活,因为我无法动态决定我使用的实现. (6认同)
  • 混合注释做了工作,感谢指向正确的方向 (2认同)

ano*_*932 5

可以在这里找到带有非常清晰示例的完整答案:/sf/answers/2127068611/

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

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

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


小智 5

如果您不想用额外的字段污染您的 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后为 ObjectMapper 注册这个模块就可以了(Zoo 是具有 Animal 字段的容器类)。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new AnimalModule());
return objectMapper.readValue(json, Zoo.class);
Run Code Online (Sandbox Code Playgroud)