我正在使用杰克逊来反序列化可能包含映射变量空值的 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 时,它会覆盖字段,并将names
、descriptions
和 nicknames
设置为 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
自定义序列化(请注意,它不能用于"不写入任何内容",因为它不控制属性名称的写入)。