JSON对象的通用PO JO,可以采用不同类型的值

问题描述 投票:0回答:2

我有一个带有已定义架构的json有效负载(rest api的请求有效负载),但是有一个属性可以采用一组未知键值对。每个属性的值可以具有不同的类型,例如数字,字符串,数组,范围,日期等。如何为该属性创建POJO并使反序列化工作相同?

我目前正在考虑为我的Property类编写一个自定义反序列化器,在其中检查值的类型并相应地执行一些自定义逻辑。

这看起来是一个典型的要求。我觉得杰克逊或格森应该有一些我想念的东西。如果它已经存在,我很想重用。我环顾四周,但到目前为止找不到一个好的答案。任何建议,将不胜感激。

{
  "id": 1234,
  "name": "test name 1",
  "properties": [
    {
      "key_a": 100
    },
    {
      "key_b": [
        "string1",
        "string2",
        "string3"
      ]
    },
    {
      "key_c": {
        "range": {
          "min": 100,
          "max": 1000
        }
      }
    }
  ]
}

我以为我的POJO属性对象看起来像这样。

class Property {
   private String key;
   private Value value; 
}
java json jackson gson json-deserialization
2个回答
0
投票

如果我理解正确,您想改回JSON。我使用ObjectMapper为自己的SpringBoot项目编写了一个小类

@Component
public final class JsonUtils {

    private final ObjectMapper mapper;

    @Autowired
    public JsonUtils(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    public String asJsonString(final Object object) {
        try {
            return mapper.registerModule(new JavaTimeModule())
                    .writeValueAsString(object);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /*
     * Customized Objectmapper for reading values compatible with this class' other methods
     * @Return the desired object you want from a JSON
     * IMPORTANT! -your return object should be a class that has a @NoArgsConstructor-
     */
    public Object readValue(final String input, final Class<?> classToRead) {
        try {
            return mapper
                    .readValue(input, classToRead);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}`

也许它对您有用。


0
投票

可以使用继承。这是您使用Jackson进行示例的类

public class Sample {

    @JsonProperty(value = "id")
    Integer id;
    @JsonProperty(value = "name")
    String name;
    @JsonProperty(value = "properties")
    List<Property> properties;
}


@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
        @JsonSubTypes.Type(value = KeyA.class, name = "key_a"),
        @JsonSubTypes.Type(value = KeyB.class, name = "key_b"),
        @JsonSubTypes.Type(value = KeyC.class, name = "key_c")
})
public abstract class Property {
}

public class KeyA extends Property{
    Integer value;

    public KeyA(Integer value) {
        this.value = value;
    }
    @JsonValue
    public Integer getValue() {
        return value;
    }
}

public class KeyB  extends Property {

    List<String> valueList;


    @JsonCreator
    public KeyB( List<String> valueList) {
        this.valueList = valueList;
    }

    @JsonValue
    public List<String> getValueList() {
        return valueList;
    }

}

public class KeyC  extends Property {
   @JsonProperty(value = "range")
    Range value;

}

public class Range {
    @JsonProperty(value = "min")
    Integer min;
    @JsonProperty(value = "max")
    Integer max;
}
© www.soinside.com 2019 - 2024. All rights reserved.