问题描述
我有一个Java对象结果 :
public class MetaData {
private List<AttributeValue<String,Object>> properties
private String name
...
... getters/setters ...
}
AttributeValue类是通用键值类。 有可能嵌套不同的AttributeValue。 (value) 对象将是另一个AttributeValue,依此类推。
由于遗留原因,不能改变该对象的结构。
我有我的JSON,我试图映射到这个对象。 一切顺利的常规属性。 此外,列表的第一级填充了AttributeValues。
问题是对象 。 杰克逊不知道如何解释这种嵌套行为,只是让它成为LinkedHashMap。
我正在寻找一种实现自定义行为的方法来告诉Jackson这必须是一个AttributeValue对象而不是LinkedHashMap。
这就是我目前正在转换JSON的方式:
ObjectMapper om = new ObjectMapper();
MetaData metaData = om.readValue(jsonString, new TypeReference<MetaData>(){});
这是JSON的示例。 (这是通过将现有的MetaData对象序列化为JSON获得的,我完全控制了这种语法)。
{
"properties":[
{
"attribute":"creators",
"value":[
{
"attribute":"creator",
"value":"user1"
},{
"attribute":"creator",
"value":"user2"
}
]
},{
"attribute":"type",
"value": "question"
}
],
"name":"example"
}
(顺便说一句:我使用GSON尝试过相同的操作,但是对象是一个StringMap,问题是一样的。使用GSON的解决方案也很受欢迎)。
编辑在 ,StaxMan发表了一条评论:“ LinkedHashMap仅在缺少类型信息时返回(或者如果Object.class被定义为类型)。 ”
后者似乎是这里的问题。 有没有办法可以覆盖这个?
1楼
如果您可以控制序列化,请尝试在mapper上调用enableDefaultTyping()
。
考虑这个例子:
Pair<Integer, Pair<Integer, Integer>> pair = new Pair<>(1, new Pair<>(1, 1));
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(pair);
Pair result = mapper.readValue(str, Pair.class);
如果没有enableDefaultTyping()
,我会有str = {"k":1,"v":{"k":1,"v":1}}
它会反序列化为LinkedHashMap
一Pair
。
但是如果我在mapper
上enableDefaultTyping()
,那么str = {"k":1,"v":["Pair",{"k":1,"v":1}]}
然后完全反序列化为Pair<Integer, Pair<...>>
。