我正在使用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时,它会覆盖字段,并将names
,descriptions
和nicknames
设置为空。
是否有通用方法,所以每次有新的地图属性时我都不必添加代码?
答案 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值(注意它不能用于“不写任何东西”,因为它不能控制写下财产名称)。