我有一个Java对象结果:
public class MetaData {
private List<AttributeValue<String,Object>> properties
private String name
...
... getters/setters ...
}
AttributeValue 类是一个通用的键值类。可能存在不同的AttributeValue嵌套。 (值) Object 将是另一个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的解决方案。)
修改在Using Jackson ObjectMapper with Generics to POJO instead of LinkedHashMap中有来自StaxMan的评论: &#34; LinkedHashMap仅在缺少类型信息时返回(或者如果Object.class被定义为类型)。&#34;
后者似乎是这里的问题。有没有办法可以覆盖它?
答案 0 :(得分:1)
如果您可以控制序列化,请尝试在地图工具上调用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}}
将Pair
反序列化为LinkedHashMap
enableDefaultTyping()
。
但如果我mapper
上的str = {"k":1,"v":["Pair",{"k":1,"v":1}]}
,那么Pair<Integer, Pair<...>>
会完全反序列化为{{1}}。