java - 基于父属性反序列化 json 子类型

标签 java json spring-boot jackson

我有一个带有动态 attribute 子项的 json,如下所示:

{  
  "label":"Some label",
  "attribute": {     <--- Dynamic attribute object
    "type": "TEXT",  <--- Field used to map `attribute` dynamic (inside child object)
    "languages":[
      {
          "language":"en_EN",
          "text":"do you approve?"
      }
    ]
  }
}

或者

{  
  "label":"Some label",
  "attribute": {
    "type": "NUMBER",
    "value: "10.0"
  }
}

我可以使用 @JsonSubTypes 和这段代码正确反序列化上面的 json:

@Data
public class Field {
    private String label;
    private Attribute attribute;
}

@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Attribute.NumberAttribute.class, name = "NUMBER"),
    @JsonSubTypes.Type(value = Attribute.TextAttribute.class, name = "TEXT")
})
public class Attribute {
    private AttributeType type;

    @Data
    public static class TextAttribute extends Attribute {
        List<Language> languages;
    }

    @Data
    public static class NumberAttribute extends Attribute {
        String value;
    }

    @Data
    public static class Language {
        private String text;
        private String language;
    }
}

但是,我遇到的问题是我必须使用属性对象内部的 type 字段,并且我需要将类型移动到父对象。结尾的json应该是这样的:

{  
  "type": "TEXT",  <--- Field used to map `attribute` dynamic (in parent object)
  "label":"Some label",
  "attribute": {   <--- Dynamic attribute object
    "languages":[
      {
          "language":"en_EN",
          "text":"do you approve?"
      }
    ]
  }
}

或者

{  
  "type": "NUMBER",
  "label":"Some label",
  "attribute": {
    "value: "10.0"
  }
}

我找不到任何方法来使用父字段(或 json 路径方式)来使用动态子类型之外的 type 属性。你知道我该怎么做吗?

最佳答案

您可以通过将 include = As.EXTERNAL_PROPERTY 添加到 @JsonTypeInfo 来实现。您只需将注释移动到该字段即可。

请参阅 EXTERNAL_PROPERTY 的 JavaDoc:

Inclusion mechanism similar to PROPERTY, except that property is included one-level higher in hierarchy [...]

这是一个例子:

@Data
class Field {
    private String label;
    private AttributeType attributeType;
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.EXTERNAL_PROPERTY, property = "attributeType")
    private Attribute attribute;
}

@Data
@JsonSubTypes({
        @JsonSubTypes.Type(value = Attribute.NumberAttribute.class, name = "NUMBER"),
        @JsonSubTypes.Type(value = Attribute.TextAttribute.class, name = "TEXT")
})
abstract class Attribute {
    @Data
    public static class TextAttribute extends Attribute {
        List<Language> languages;
    }

    @Data
    public static class NumberAttribute extends Attribute {
        String value;
    }

    @Data
    public static class Language {
        private String text;
        private String language;
    }
}

enum AttributeType {
    NUMBER, TEXT;
}

关于java - 基于父属性反序列化 json 子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63455860/

相关文章:

java - Hibernate映射异常: unknown entity

json - 带有 postgres 的 Django 的非关系数据库模式

java - 如何使用 Spring Boot 外部化配置?

java - 使用 Maven 的 Spring Boot 示例不会在代理后面编译

java - Intellij 运行 Spring Boot 应用程序时没有运行按钮

java - 用Java计算交易费用

java - 使用 while 循环时如何解决此错误消息?

java - Spring : Default html error page is not properly displayed?

php - 排序 json 对象 laravel

python - 类型错误 : Object of type 'float32' is not JSON serializable