6

我正在使用 Jackson 反序列化可能包含 Map 变量的空值的 JSON。我想要的是如果值为空,我希望地图是一个空的 HashMap 而不是空的。

JSON:

{"names":null, "descriptions":null, "nicknames":null...}

Java类:

private User {
    private Map<String,String> names = new HashMap<>();
    private Map<String,String> descriptions = new HashMap<>();
    private Map<String,String> nicknames = new HashMap<>();
}

现在,当ObjectMapper反序列化 JSON 时,它会覆盖字段,并将 、 和 设置namesdescriptionsnull nicknames

有没有一种通用的方法,所以每次我有一个新的地图属性时我都不必添加代码?

4

3 回答 3

6

为您的地图添加二传手:

public void setNames(Map<String, String> names) {
    this.names = (names == null) ? new HashMap<>() : names;
}

这个 setter 将被 Jackson 检测到,并将在从 JSON 读取属性时使用。因此,在您的 setter 中,您可以检查该值是否为 null,如果是,则创建一个新的 HashMap。

于 2013-11-08T19:28:47.780 回答
6

您可以设置自己的模块并覆盖getNullValue()

见文档 http://jackson.codehaus.org/1.9.9/javadoc/org/codehaus/jackson/map/JsonDeserializer.html

笔记

我为所有人注册了反序列化器Map.class,不是那么精确

测试代码

    SimpleModule module = new SimpleModule("test",  new Version(1, 0, 0, null));

    module.addDeserializer(Map.class, new JsonDeserializer<Map>() {
        @Override
        public Map deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            return jp.readValueAs(HashMap.class);
        }

        @Override
        public Map getNullValue() {
            return new HashMap();
        }
    });

    mapper.registerModule(module);

测试用例

String s = "{\"names\":{\"1\":2}, \"descriptions\":null, \"nicknames\":null}";

结果

User{descriptions={}, names={1=2}, nicknames={}}
于 2013-11-08T21:32:04.287 回答
1

随着最近发布的 Jackson 2.3.0,有一个新选项:

public class POJO {
   @JsonSerialize(nullsUsing=MyNullSerializer.class)
   public Map<String,Object> stuff;
}

这样您就可以定义仅用于null将给定属性的值序列化为任何有效 JSON 值的自定义序列化(请注意,它不能用于“不写任何东西”,因为它不控制属性名称的写入)。

于 2013-11-16T01:41:03.277 回答