java - jackson : Inheritance and required attributes

标签 java json jackson polymorphism jackson2

我目前正在尝试使用能够处理多态性的 jackson 实现反序列化器,也就是说,给定这两个类:

public abstract class Animal {
  private String name;
  private float weight;

  @JsonCreator
  protected Animal(@JsonProperty(value="name") String name, @JsonProperty(value="weight",required=true) int weight) {
      this.name=name;
      this.weight=weight;
  }
}

public class Dog extends Animal {
    private int barkVolume;

    @JsonCreator
    public Dog(String name,int weight, @JsonProperty(value="barkVolume",required=true) int barkVolume) {
        super(name, weight);
        this.barkVolume=barkVolume;
    }

}

反序列化器应该能够从 json 字符串中推断和实例化正确的子类。

我使用自定义反序列化器模块 UniquePropertyPolymorphicDeserializer(来自 https://gist.github.com/robinhowlett/ce45e575197060b8392d)。该模块配置如下:

UniquePropertyPolymorphicDeserializer<Animal> deserializer =
             new UniquePropertyPolymorphicDeserializer<Animal>(Animal.class);

        deserializer.register("barkVolume", Dog.class);

        SimpleModule module = new SimpleModule("UniquePropertyPolymorphicDeserializer");
        module.addDeserializer(Animal.class, deserializer);
        mapper.registerModule(module);

该模块向用户询问 Animal 的每个子类的独特属性。因此,当反序列化器找到一个带有 barkVolume 属性的 json 字符串时,它知道应该实例化一个 Dog。

但是,我对 json 属性的规范有疑问,因为子类不能从父类中给定的属性继承。在 Dog 类中,我必须再次指定“name”和“weight”是 json 属性,即使这些属性已经在 Animal 类中指定:

public Dog(@JsonProperty(value="name") String name, @JsonProperty(value="weight",required=true) int weight, @JsonProperty(value="barkVolume",required=true) int barkVolume) {
        super(name, weight);
        this.barkVolume=barkVolume;
    }

否则,反序列化器会产生错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid type definition for type `Animals.Dog`: Argument #0 has no property name, is not Injectable: can not use as Creator [constructor for Animals.Dog, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}]
 at [Source: UNKNOWN; line: -1, column: -1]

这个解决方案对我来说并不令人满意:

  1. 每次我们想要创建一个新的 Animal 子类时,我们必须 在该类中指定name和weight为json属性

  2. 这很棘手,例如,在 Animal 类中,weight 属性被标记为必需属性,而在子类中,我们可以定义 weight 不是必需属性。

您是否知道一种从父类的属性中“继承”的方法,从而避免在子类中每次都指定相应的 json 属性?

最好的问候,

马修

最佳答案

我最终决定创建自己的 Deserializer(而不是 UniquePropertyDeserializer),我在其中使用内省(introspection)来获取父类的字段。它允许避免在子类中再次指定所需的 json 属性。

关于java - jackson : Inheritance and required attributes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51043066/

相关文章:

java - JSON数组的反序列化

java - 如何在 spring mvc 中将 .json 映射到 .html url

java - 使用 Jackson JSON 反序列化和嵌套类?

java - 我正在尝试使用 boilerpipe 库在 java 中提取文章

java - 从存储在 HashMap 中的类创建新实例

java - 在 JBoss 中使用代理服务器配置 Websphere MQConnectionFactory

javascript - 单击按钮时我无法增加变量的值

Java Web 应用程序在缓慢的 MySQL 查询中停止

java - 如何使用 GSON 解析 JSON 文件

javascript - 如何通过 JSON/JS 在 Jenkins 中为 CSRF 添加面包屑