1. 概述
在本文中,我們將探討使用 Jackson 處理包含空值或空鍵的 Map 的高級用法。
2. 忽略 Map 中空值
Jackson 提供了一種簡單但實用的方法,可以全局控制 Map 在序列化時對空值的處理方式:
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. 使用空鍵序列化 Map
默認情況下,Jackson 不允許使用空鍵序列化 Map。 如果您嘗試寫入此類 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("");
}
}現在,帶有空鍵的地圖將正常工作——空鍵將被寫入為空字符串:
@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 字段。 您可以查看此教程以瞭解確切的用法。
5. 結論
序列化 Map 對象在常見場景中十分普遍,因此我們需要一個能夠很好地處理序列化過程細微之處的庫。 Jackson 提供了幾個方便的自定義選項,可以幫助你很好地塑造這個序列化過程的輸出。
它還提供了許多處理集合的實用方法。