当前位置: 代码迷 >> java >> Jackson Unmarshall自定义对象而不是LinkedHashMap
  详细解决方案

Jackson Unmarshall自定义对象而不是LinkedHashMap

热度:73   发布时间:2023-08-04 09:27:48.0

我有一个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被定义为类型)。

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

如果您可以控制序列化,请尝试在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}}它会反序列化为LinkedHashMapPair

但是如果我在mapperenableDefaultTyping() ,那么str = {"k":1,"v":["Pair",{"k":1,"v":1}]}然后完全反序列化为Pair<Integer, Pair<...>>

  相关解决方案