I usually post about Jackson and JSON stuff on Twitter - you can follow me there:

1. Overview

This quick tutorial is going to cover how to set up Jackson 2 to ignore null fields when serializing a java class.

If you want to dig deeper and learn other cool things you can do with the Jackson 2 – head on over to the main Jackson tutorial.

2. Ignore Null Fields on the Class

Jackson allows controlling this behavior at either the class level:

@JsonInclude(Include.NON_NULL)
public class MyDto { ... }

Or – more granularity – at the field level:

public class MyDto {

    @JsonInclude(Include.NON_NULL)
    private String stringValue;

    private int intValue;

    // standard getters and setters
}

Now, we should be able to test that null values are indeed not part of the final JSON output:

@Test
public void givenNullsIgnoredOnClass_whenWritingObjectWithNullField_thenIgnored()
  throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    MyDto dtoObject = new MyDto();

    String dtoAsString = mapper.writeValueAsString(dtoObject);

    assertThat(dtoAsString, containsString("intValue"));
    assertThat(dtoAsString, not(containsString("stringValue")));
}

3. Ignore Null Fields Globally

Jackson also allows configuring this behavior globally on the ObjectMapper:

mapper.setSerializationInclusion(Include.NON_NULL);

Now any null field in any class serialized through this mapper is going to be ignored:

@Test
public void givenNullsIgnoredGlobally_whenWritingObjectWithNullField_thenIgnored() 
  throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(Include.NON_NULL);
    MyDto dtoObject = new MyDto();

    String dtoAsString = mapper.writeValueAsString(dtoObject);

    assertThat(dtoAsString, containsString("intValue"));
    assertThat(dtoAsString, containsString("booleanValue"));
    assertThat(dtoAsString, not(containsString("stringValue")));
}

4. Conclusion

Ignoring null fields is such a common Jackson configuration because it’s often the case that we need to have better control over the json output. This article shows how to do that for classes – there are however more advanced usecases, such as ignoring null values when serializing a Map – which is covered here.

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.

I usually post about Jackson and JSON stuff on Twitter - you should follow me there:


  • Colm McHugh

    What if you don’t want to ignore nulls? Is that the default behavior?

    • Hey Colm,
      At a high level, there are two things to keep in mind here – serialization and deserialization. By default, nulls aren’t ignored on either.
      Hope that clears things up. Cheers,
      Eugen.

  • xAt0mz

    Hi there,

    @JsonInclude(Include.NON_NULL) only works for serialization, but what about deserialization ? I mean, when having { “foo”:null } as JSON results in field “foo” = null in new object instance after deserialization. Is there a way to avoid it and to force Jackson passing over null field ?

    To get some context, I’m using Jersey (REST API library) with Jackson for JSON support.

    When I’m getting a request with something like { “foo”:null, “bar”:”123″ } as JSON, matching with object A{String foo; String bar;} Jersey first creates and instance of A (with default values if specified in constructor or behind fields), then deserialize JSON to a temporary object A’, then copies all JSON fields that were specified in JSON from A’ to A. If I have default values in A-class constructor, and have fields equal to null in JSON, all my default values are erased and replaced by null (so in my previous example, if I have a default value for “foo” field, it will be replaced by null in object).

    Do you know if there is a way to specify Jackson deserializer to ignore null fields during deserialization ? Or is this a Jersey-related behavior ?

    Cheers,

    • That’s a good point. Note that it’s the first thing the article start with – the fact that this is focus on serialization.
      Now – on to your deserialization question – there are ways of doing that (a custom deserializer for instance).

      However, I would actually take a step back here and suggest that if you have logic in the constructor, you may want to use this limitation of Jackson as a suggestion of a code smell, and rather than working around it (which you can) – try to work on your domain design, and get to use standard POJOs. Have a look at this writeup for a bit more info on that.
      Now, I realize that’s likely to involve a lot more work than simply working around it, so it may or may not be an option.

      Hope that helps.
      Cheers,
      Eugen.