Jackson – 使用映射和空值

Data,Jackson
Remote
0
12:53 AM · Dec 01 ,2025

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("");
    }
}

現在,包含空鍵的 Map 將正常工作——空鍵將被寫入為空字符串:

@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 提供了幾個方便的自定義選項,可以很好地塑造這個序列化過程的輸出。

它還提供了許多處理集合的實用方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.