Jackson将Map变量反序列化为空Map而不是null

时间:2013-11-08 19:24:32

标签: java json jackson deserialization

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

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时,它会覆盖字段,并将namesdescriptionsnicknames设置为空。

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

3 个答案:

答案 0 :(得分:5)

为地图添加一个setter:

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

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

答案 1 :(得分:5)

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

见doc 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={}}

答案 2 :(得分:0)

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

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

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