代码之家  ›  专栏  ›  技术社区  ›  Egor Stepanov

当value1的java类依赖于value2时,如何使用jackson反序列化JSON

  •  1
  • Egor Stepanov  · 技术社区  · 5 年前

    我有一个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
        }
      ]
    }
    

    这是一些实体的列表,它们有参数 类型 价值 取决于 类型 ,param 价值 具有特定的代表性。

    例如:

    • 类型 菲奥 然后 是包含两个字段的复杂对象: 姓氏
    • 如果 类型 地理位置 然后 价值 是包含字段的复杂对象: , 城市 , ...
    • 数字 然后 价值

    我创建了一个abstract类 实体值 我使用了jackson注释:

    @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 ...
    }
    

    菲奥 但我和一个 数字 它像一个复杂对象一样进行序列化和反序列化,而不像前面提到的示例。

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

    谢谢

    1 回复  |  直到 5 年前
        1
  •  1
  •   Prabhakar D    5 年前

      @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}]}