使用 Jackson 反序列化 JSON 实体的动态属性
Deserialization of dynamic attribute of JSON entity using Jackson
有 JSON 个实体具有 value
动态属性:
{
"name" : "name1",
"value" : {"different structures: strings, enums, arrays, custom entities"}
}
Java实体表示:
public class Entity {
public String name;
public Object value;
}
在value
中可以传递完全不同的JSON结构。每次value
应该映射到不同的POJO。
除了 value
属性内容(Map<String, String>
结构)的额外反序列化之外,是否有任何通用方法将 value
属性反序列化为特定实体?
我使用 @JsonSubTypes
(序列化为不同类型)或 @JsonDeserialize
(自定义序列化)来执行此操作。您可以在 https://www.baeldung.com/jackson-annotations
查看一些示例
您始终可以将任何有效的 JSON 文档反序列化为 class Map<String, Object>
,而不必进行 "additional" 反序列化。只需将 public Object value;
更改为 public Map<String, Object> value;
即可。
为了知道我应该反序列化的确切类型 value
应该添加新属性 valueType
。
此外,应实现自定义反序列化程序以处理所需类型的反序列化。
Entity
class 使用 valueType
和 @JsonDeserialize
注释扩展:
public class Entity {
public String name;
@JsonDeserialize(using = EntityValueDeserializer.class)
public Object value;
public Class valueType;
}
JSON对应修改为:
{
"name" : "name1",
"value" : "some string" | 10 | "any custom entity",
"valueType" : "java.lang.String" | "java.lang.Integer" | "any custom type"
}
然后实现获取 valueType
的自定义反序列化器 EntityValueDeserializer
并将 value
反序列化为 valueType
:
public class EntityValueDeserializer extends JsonDeserializer<Object>
{
public Object deserialize(JsonParser jp, DeserializationContext ctx) throws IOException
{
ObjectCodec codec = jp.getCodec();
JsonNode node = codec.readTree(jp);
Entity entity = ((Entity) jp.getParsingContext().getCurrentValue());
return codec.treeToValue(node, entity.valueType);
}
}
有 JSON 个实体具有 value
动态属性:
{
"name" : "name1",
"value" : {"different structures: strings, enums, arrays, custom entities"}
}
Java实体表示:
public class Entity {
public String name;
public Object value;
}
在value
中可以传递完全不同的JSON结构。每次value
应该映射到不同的POJO。
除了 value
属性内容(Map<String, String>
结构)的额外反序列化之外,是否有任何通用方法将 value
属性反序列化为特定实体?
我使用 @JsonSubTypes
(序列化为不同类型)或 @JsonDeserialize
(自定义序列化)来执行此操作。您可以在 https://www.baeldung.com/jackson-annotations
您始终可以将任何有效的 JSON 文档反序列化为 class Map<String, Object>
,而不必进行 "additional" 反序列化。只需将 public Object value;
更改为 public Map<String, Object> value;
即可。
为了知道我应该反序列化的确切类型 value
应该添加新属性 valueType
。
此外,应实现自定义反序列化程序以处理所需类型的反序列化。
Entity
class 使用 valueType
和 @JsonDeserialize
注释扩展:
public class Entity {
public String name;
@JsonDeserialize(using = EntityValueDeserializer.class)
public Object value;
public Class valueType;
}
JSON对应修改为:
{
"name" : "name1",
"value" : "some string" | 10 | "any custom entity",
"valueType" : "java.lang.String" | "java.lang.Integer" | "any custom type"
}
然后实现获取 valueType
的自定义反序列化器 EntityValueDeserializer
并将 value
反序列化为 valueType
:
public class EntityValueDeserializer extends JsonDeserializer<Object>
{
public Object deserialize(JsonParser jp, DeserializationContext ctx) throws IOException
{
ObjectCodec codec = jp.getCodec();
JsonNode node = codec.readTree(jp);
Entity entity = ((Entity) jp.getParsingContext().getCurrentValue());
return codec.treeToValue(node, entity.valueType);
}
}