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

7
我将使用Jackson来反序列化一个JSON,这个JSON可能包含Map变量的null值。我的要求是,如果该值为null,则希望该Map变量成为空的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 设置为 null。

是否有一种通用的方法,使我不必每次添加新的映射属性时都要添加代码?

3个回答

6
添加一个地图的设置器:
public void setNames(Map<String, String> names) {
    this.names = (names == null) ? new HashMap<>() : names;
}

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


1
更简洁地说,this.names = (names == null) ? new HashMap<>() : names; - 或者如果您有Guava,则使用Objects.firstNonNull() - Matt Ball
@MattBall 谢谢,我正要编辑并改进那一部分 :) - Simon Forsberg
有没有一种通用的方法可以做到这一点,这样每次我在属性中添加新地图时就不必添加代码了? - Glide
@Glide 你可以尝试创建自己的Map反序列化器,但我不确定在这种情况下是否推荐这样做。你也可以在反序列化对象后调用一个方法,为那些为空的属性创建新的HashMap。 - Simon Forsberg

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

1
最近发布的Jackson 2.3.0中有一个新选项:
public class POJO {
   @JsonSerialize(nullsUsing=MyNullSerializer.class)
   public Map<String,Object> stuff;
}

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接