【问题标题】:How to deserialize JSON with jackson when java class of value1 depends on value2java - 当value1的java类依赖于value2时如何用jackson反序列化JSON
【发布时间】:2019-02-08 18:40:46
【问题描述】:

我有一个 JSON 字符串:

{
  "entities": [
    {
      "type": "fio",
      "value": {
        "firstName": "first",
        "lastName": "last"
      }
    },

    {
      "type": "geo",
      "value": {
        "country": "the country",
        "city": "the city"
      }
    },

    {
      "type": "number",
      "value": 100
    },

    {
      "type": "number",
      "value": 3.14
    }
  ]
}

这是一些实体的列表,具有参数 type 和 value。 根据 type,参数 value 具有特定的表示形式。

例如:

  • 如果 type 是 fio,则 value 是一个包含 2 个字段的复杂对象:firstName 和 姓氏。
  • 如果 type 是 geo,则 value 是一个包含字段的复杂对象: 国家、城市、...
  • 如果 type 是 number,则 value 是一个普通数字(long 或 double)

我创建了一个抽象类EntityValue,实现很少。 我使用了杰克逊注解:

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME, 
  include = JsonTypeInfo.As.PROPERTY, 
  property = "type")
@JsonSubTypes({ 
  @Type(value = GeoEntityValue.class, name = "geo"), 
  @Type(value = FioEntityValue.class, name = "fio"),
  ... 
})
public class Entity {

    private final EntityType type;
    private final EntityValue value;

    ... constructor and getters ...
}

它非常适用于像 fio 或 geo 这样的复杂类型, 但我在 number 类型中挣扎。 它像一个复杂的对象一样序列化和反序列化,而不是像开头提到的例子。

您能帮我管理杰克逊注释或重新组织类层次结构以使序列化和反序列化工作吗?

谢谢!

【问题讨论】:

    标签: java json serialization jackson deserialization


    【解决方案1】:

    这是一个可行的解决方案:

      @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = As.PROPERTY,
        property = "type")
    @JsonSubTypes(value = {
        @Type(value = GeoEntity.class, name = "geo"),
        @Type(value = FioEntity.class, name = "fio"),
        @Type(value = Number.class, name ="number")
    })
    public abstract class Entity {
    
      public void setType(String type) {
        this.type = type;
      }
    
      private String type;
    
      @Override
      public String toString(){
        return ToStringBuilder.reflectionToString(this);
      }
    
    }
    

    FioEntity 类(类似我们可以创建 GeoEntity 的方式)

        public class FioEntity extends Entity {
    
          public FioEntityValue getValue() {
            return value;
          }
    
          public void setValue(FioEntityValue value) {
            this.value = value;
          }
    
          private FioEntityValue value;
    
    
        public class FioEntityValue extends  EntityValue{
    
          private String firstName;
    
          private String lastName;
    
    
          public String getLastName() {
            return lastName;
          }
    
          public void setLastName(String lastName) {
            this.lastName = lastName;
          }
    
          public String getFirstName() {
            return firstName;
          }
    
          public void setFirstName(String firstName) {
            this.firstName = firstName;
          }
        }
       }
    

    数字类:

    public class Number extends Entity {
    
      private Double value;
    
      public Double getValue() {
        return value;
      }
    
      public void setValue(Double value) {
        this.value = value;
      }
    
    }
    

    测试类:

    public class Test {
    
      public static void main(String[] args) throws IOException {
    
    
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
        String content = "{\n"
            + "  \"entities\": [\n"
            + "    {\n"
            + "      \"type\": \"fio\",\n"
            + "      \"value\": {\n"
            + "        \"firstName\": \"first\",\n"
            + "        \"lastName\": \"last\"\n"
            + "      }\n"
            + "    },\n"
            + "\n"
            + "    {\n"
            + "      \"type\": \"geo\",\n"
            + "      \"value\": {\n"
            + "        \"country\": \"the country\",\n"
            + "        \"city\": \"the city\"\n"
            + "      }\n"
            + "    },\n"
            + "\n"
            + "    {\n"
            + "      \"type\": \"number\",\n"
            + "      \"value\": 100\n"
            + "    },\n"
            + "\n"
            + "    {\n"
            + "      \"type\": \"number\",\n"
            + "      \"value\": 3.14\n"
            + "    }\n"
            + "  ]\n"
            + "}";
    
        Entities test = mapper.readValue(content, Entities.class);
    
        System.out.println(mapper.writeValueAsString(test));
    
    
      }
    
    }
    

    输出:

     {"entities":[{"type":"fio","value":{"firstName":"first","lastName":"last"}},{"type":"geo","value":{"city":"the city","country":"the country"}},{"type":"number","value":100.0},{"type":"number","value":3.14}]}
    

    【讨论】:

    • 谢谢你,这对我帮助很大!
    • 我很高兴它有帮助
    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多