Jackson序列化 Map 对象中空值
Contents
1. 概述
在这篇快速文章中,我们将研究一个更高级的使用Jackson 的用例——使用包含空值或空键的Map。
2. 忽略映射中的空值
Jackson 有一种简单但有用的方法来全局控制 Map 被序列化时 null 值发生的情况:
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
现在通过此映射器序列化的 Map 对象中的任何空值都将被忽略:
@Test
public void givenIgnoringNullValuesInMap_whenWritingMapObjectWithNullValue_thenIgnored()
throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
MyDto dtoObject1 = new MyDto();
Map<String, MyDto> dtoMap = new HashMap<String, MyDto>();
dtoMap.put("dtoObject1", dtoObject1);
dtoMap.put("dtoObject2", null);
String dtoMapAsString = mapper.writeValueAsString(dtoMap);
assertThat(dtoMapAsString, containsString("dtoObject1"));
assertThat(dtoMapAsString, not(containsString("dtoObject2")));
}
3. 使用 Null 键序列化映射
默认情况下,Jackson 不允许使用 null key 对 Map 进行序列化。如果你尝试写出这样的地图,你会得到以下异常:
c.f.j.c.JsonGenerationException:
Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)
at c.f.j.d.s.i.FailingSerializer.serialize(FailingSerializer.java:36)
然而,该库足够灵活,您可以定义自定义的空键序列化程序并覆盖默认行为:
class MyDtoNullKeySerializer extends StdSerializer<Object> {
public MyDtoNullKeySerializer() {
this(null);
}
public MyDtoNullKeySerializer(Class<Object> t) {
super(t);
}
@Override
public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused)
throws IOException, JsonProcessingException {
jsonGenerator.writeFieldName("");
}
}
现在带有 null 键的 Map 可以正常工作——并且 null 键将被写为一个空字符串:
@Test
public void givenAllowingMapObjectWithNullKey_whenWriting_thenCorrect()
throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializerProvider().setNullKeySerializer(new MyDtoNullKeySerializer());
MyDto dtoObject = new MyDto();
dtoObject.setStringValue("dtoObjectString");
Map<String, MyDto> dtoMap = new HashMap<String, MyDto>();
dtoMap.put(null, dtoObject);
String dtoMapAsString = mapper.writeValueAsString(dtoMap);
assertThat(dtoMapAsString, containsString("\"\""));
assertThat(dtoMapAsString, containsString("dtoObjectString"));
}
4. 忽略空字段
除了 Maps,Jackson 还提供了很多配置和灵活性来忽略/处理一般的null字段。您可以查看本教程 以确切了解其工作原理。