Jackson Unmarshall 自定义对象而不是 LinkedHashMap

use*_*803 7 java json jackson

我有一个 Java 对象结果

public class MetaData {
    private List<AttributeValue<String,Object>> properties
    private String name
    ...

    ... getters/setters ...
}
Run Code Online (Sandbox Code Playgroud)

的AttributeValue类是通用的键值类。可能嵌套了不同的 AttributeValue。(value) Object将是另一个 AttributeValue 等等。

由于遗留原因,无法更改此对象的结构。

我有我的 JSON,我尝试将其映射到此对象。对于常规属性,一切顺利。此外,列表的第一级填充有 AttributeValues。

问题是Object。Jackson 不知道如何解释这种嵌套行为,只是将其设为 LinkedHashMap。

我正在寻找一种实现自定义行为的方法来告诉杰克逊这必须是一个 AttributeValue 对象而不是 LinkedHashMap。

这就是我目前转换 JSON 的方式:

ObjectMapper om = new ObjectMapper();
MetaData metaData = om.readValue(jsonString, new TypeReference<MetaData>(){});
Run Code Online (Sandbox Code Playgroud)

这是示例 JSON。(这是通过将现有 MetaData 对象序列化为 JSON 获得的,我可以完全控制此语法)。

{
    "properties":[
        {
            "attribute":"creators",
            "value":[
                {
                    "attribute":"creator",
                    "value":"user1"
                },{
                    "attribute":"creator",
                    "value":"user2"
                }
            ]
        },{
            "attribute":"type",
            "value": "question"
        }
    ],
    "name":"example"
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句:我已经使用 GSON 尝试过相同的方法,但是对象是 StringMap 并且问题是相同的。也欢迎使用 GSON 的解决方案)。

编辑将 Jackson ObjectMapper 与泛型用于 POJO 而不是 LinkedHashMap 中有来自 StaxMan 的评论:“ LinkedHashMap 仅在缺少类型信息时返回(或者如果 Object.class 被定义为类型)。

后者似乎是这里的问题。有没有办法可以覆盖它?

hot*_*key 2

如果您可以控制序列化,请尝试调用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);
Run Code Online (Sandbox Code Playgroud)

如果没有enableDefaultTyping(),我会将str = {"k":1,"v":{"k":1,"v":1}}which 反序列化为Pairwith LinkedHashMap

但如果我enableDefaultTyping()打开mapper,那么str = {"k":1,"v":["Pair",{"k":1,"v":1}]}它就会完美地反序列化为Pair<Integer, Pair<...>>.