适用于 JSON 对象的通用 POJO,可以采用不同类型的值



我有一个具有定义架构的 json 有效负载(rest API 的请求有效负载(,但有一个属性可以接受未知键值对的数组。每个属性的值可以是不同类型的,如数字、字符串、数组、范围、日期等。如何为此属性创建 POJO 并使反序列化适用于该属性?

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

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

{
"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; 
}

为此可以使用继承。这是您与杰克逊示例的类

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;
}

如果我理解正确,您想更改为 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);
}
}
}`

也许它对你有用。

最新更新