杰克逊将 Map 变量反序列化为空 Map 而不是 null



我正在使用杰克逊来反序列化可能包含映射变量空值的 JSON。我想要的是,如果值为空,我希望地图是一个空的哈希图而不是空。

杰森:

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

爪哇类:

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。

有没有一种通用方法,这样我就不必在每次有新的地图属性时都添加代码?

您可以设置自己的模块并覆盖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={}}

为地图添加一个二传手:

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

此二传手将由 Jackson 检测到,并将在从 JSON 读取属性时使用。因此,在您的资源库中,您可以检查该值是否为空,如果是,则创建一个新的 HashMap。

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

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

以便您可以定义仅用于将给定属性的值序列化为任何有效 JSON 值null自定义序列化(请注意,它不能用于"不写入任何内容",因为它不控制属性名称的写入)。

相关内容

最新更新