为什么我无法使用 Jackson Java 库解开和序列化 Java 映射?

2022-08-31 17:08:57

我的豆子看起来像这样:

class MyBean {

    private @JsonUnwrapped HashMap<String, String> map = new HashMap<String, String>();

    private String name;

    public HashMap<String, String> getMap() {
        return map;
    }

    public void setMap(HashMap<String, String> map) {
        this.map = map;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

当我使用以下代码序列化Bean时:

MyBean bean = new MyBean();
HashMap<String, String> map = new HashMap<String, String>();;
map.put("key1", "value1");
map.put("key2", "value2");
bean.setMap(map);
bean.setName("suren");
ObjectMapper mapper = new ObjectMapper();
System.out.println("\n"+mapper.writeValueAsString(bean));

我得到的结果是这样的:

{"map":{"key2":"value2","key1":"value1"},"name":"suren"}

{"key2":"value2","key1":"value1","name":"suren"}

根据 JacksonFeatureUnpacking 文档进行预估。为什么我没有得到未包装的结果?


答案 1

@JsonUnwrapped不适用于地图,仅适用于具有 getter 和 setter 的正确 POJO。对于地图,应使用@JsonAnyGetter@JsonAnySetter(在 jackson 版本中可用 >= 1.6)。

如果您的情况,请尝试以下操作:

@JsonAnySetter 
public void add(String key, String value) {
    map.put(key, value);
}

@JsonAnyGetter
public Map<String,String> getMap() {
    return map;
}

这样,您也可以直接向地图添加属性,就像将值添加到地图中的新键一样。add('abc','xyz')abcxyz


答案 2

Jackson 项目中存在一个未解决的问题,允许在地图上提供支持。@JsonUnwrapped

在支持此功能之前,关于在另一个答案中使用/建议的解决方法似乎是要走的路,实际上是Jackson项目作者在开放问题中建议的方法@JsonAnySetter@JsonAnyGetter

根据这个:

http://www.cowtowncoder.com/blog/archives/2011/07/entry_458.html

可以使用@JsonAnyGetter/setter来做一些可能类似的事情。一个缺失的部分是,目前必须有getter(不能在Map上使用它),但这应该很容易解决。

@JsonAnySetter 
public void add(String key, String value) {
    map.put(key, value);
}

@JsonAnyGetter
public Map<String,String> getMap() {
    return map;
}