I usually post about Jackson and JSON stuff on Twitter - you can follow me there:
Follow @baeldung1. Overview
In this quick article we’re going to look at a more advanced use-case of using Jackson – working with Maps that contain null values or null keys.
2. Ignore Nulls Values in a Map
Jackson has a simple but useful way of globally controlling what happens to null values when a Map gets serialized:
ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
Now any null value in Map object serialized through this mapper is going to be ignored:
@Test public void givenIgnoringNullValuesInMap_whenWritingMapObjectWithNullValue_thenIgnored() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); 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. Serializing A Map With A Null Key
By default, Jackson doesn’t allow the serialization of a Map with a null key. If you do try to write out such a map, you’ll get the following exception:
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)
The library is however flexible enough that you can define a custom, null key serializer and override the default behavior:
class MyDtoNullKeySerializer extends JsonSerializer<Object> { @Override public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) throws IOException, JsonProcessingException { jsonGenerator.writeFieldName(""); } }
Now the Map with the null key will work just fine – and the null key will be written as an empty String:
@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. Ignore Null Fields
Besides Maps, Jackson provides a lot of configuration and flexibility for ignoring / working with null fields in general. You can check out this tutorial to see exactly how that works.
5. Conclusion
Serializing a Map object is common enough that we need a library that’s able to handle the nuances of the serialization process well. Jackson provides a few handy customization options to help you shape the output of this serialization process quite well.
It also provides a lot of solid ways to work with collections in a more general sense.
The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.