«1. Обзор

В этой быстрой статье мы рассмотрим более продвинутый вариант использования Джексона — работу с картами, которые содержат нулевые значения или нулевые ключи.

2. Игнорировать нулевые значения в карте

У Джексона есть простой, но полезный способ глобального управления тем, что происходит с нулевыми значениями при сериализации карты:

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);

Теперь любое нулевое значение в объекте карты сериализуется через этот преобразователь будет проигнорирован:

@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. Сериализация карты с нулевым ключом

По умолчанию Джексон не разрешает сериализацию карты с нулевым ключом. Если вы попытаетесь записать такую ​​карту, вы получите следующее исключение:

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. Игнорировать пустые поля

Помимо карт, Джексон предоставляет много конфигурации и гибкости для игнорирования/работы с нулевыми полями в целом. Вы можете проверить этот учебник, чтобы увидеть, как именно это работает.

5. Заключение

Сериализация объекта Map достаточно распространена, поэтому нам нужна библиотека, способная хорошо обрабатывать нюансы процесса сериализации. Джексон предоставляет несколько удобных параметров настройки, которые помогут вам достаточно хорошо формировать выходные данные этого процесса сериализации.

Он также предоставляет множество надежных способов работы с коллекциями в более общем смысле.

Реализацию всех этих примеров и фрагментов кода можно найти на GitHub — это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.