Ignore Null Fields with Jackson in Java and Spring Boot

Null values arise a lot in software development, and proper handling of null values can be turned into a science in and of itself. Jackson is the de facto library for serialization and deserialization of Java objects - and a common scenario pertains to serializing objects that have null fields.

In this short tutorial, we'll take a look at how you can ignore null fields when serializing a POJO with Jackson.

Changing the ObjectMapper Settings

Jackson's ObjectMapper is the central API that maps objects to serialized values. Naturally, you can adjust and customize the way it works through various flags, one of which is:

objectMapper.setSerializationInclusion(Include.NON_NULL);

When serializing with this mapper, properties will only be included if they're non-null.

This sets the flag globally for any object being serialized with the objectMapper instance. If you're working with Spring Boot, and the ObjectMapper it's relying on isn't exposed, you can alter the flag in the application.properties file:

spring.jackson.default-property-inclusion = non_null

Or, if you're using application.yml:

spring:
  jackson:
    default-property-inclusion: non_null

Note: Older versions of Spring used spring.jackson.serialization-inclusion=non_null instead of spring.jackson.default-property-inclusion=non_null.

Alternatively, you can peel back replace the default ObjectMapper instance by registering a new @Primary @Bean, named objectMapper(), which overrides the default implementation and allows full customization over the instance that'll be used by default when serializing and deserializing:

@Bean
@Primary
public ObjectMapper objectMapper() {
    return new ObjectMapper()
      .setSerializationInclusion(JsonInclude.Include.NON_NULL);
}

This @Bean should go into any file that's annotated with the @Configuration annotation, and is oftentimes situated either in a specialized configuration class or the main class of the Spring Boot application.

Changing the Jackson2ObjectMapperBuilder Instance

Spring uses the HttpMessageConverters to convert between HTTP messages and objects. The default converters are the ObjectMapper and XmlMapper instances instantiated via the Jackson2ObjectMapperBuilder.

Instead of manually providing the primary ObjectMapper (replacing the one provided by the builder), you can instruct Spring on how to build the object mapper instead. This allows Spring to do its high-level configurations without you tampering with the lower-level objects, while still customizing the way it works. Additionally, you can also customize the XmlMapper this way in one go.

To customize the builder, you register a new @Bean of Jackson2ObjectMapperBuilderCustomizer type, which customizes and returns the builder:

@Bean
public Jackson2ObjectMapperBuilderCustomizer customBuilder() {
    return builder -> {
      builder.serializationInclusion(JsonInclude.Include.NON_NULL);
    }
}

@JsonInclude Annotation

On the other end of the spectrum, we can use annotations, as a low-code alternative! Annotations can be applied at the class-level or method-level:

@JsonInclude(JsonInclude.Include.NON_NULL)

This allows you to customize only certain classes, instead of the global behavior of the object mapper.

Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Note: As of Jackson 2.0, the annotation's value is JsonInclude.Include.NON_NULL. For earlier versions, use include=JsonSerialize.Inclusion.NON_NULL.

@JsonInclude on Class-Level

When you apply @JsonInclude at class-level, the annotation extends to all of the getters and setters:

@Entity(name="property")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Property implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private String id;

    @Column(name="transaction_type")
    private TransactionType transactionType;

    @Column(name="property_type")
    private PropertyType propertyType;
    
    // Constructor, getters, setters, toString(), etc.
}

Any given field that has a null value won't be serialized.

@JsonInclude on Method-Level

Alternatively, you can apply the annotation at method-level as the most granular option:

@Entity(name="property")
public class Property implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private String id;

    @Column(name="transaction_type")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private TransactionType transactionType;

    @Column(name="property_type")
    private PropertyType propertyType;
    
    // Constructor, getters, setters, toString(), etc.
}

In this snippet - the annotation is only applied to the TransactionType field.

Conclusion

In this guide, you've learned how to ignore null fields in Jackson, with Java and Spring Boot. This can be achieved globally by replacing the underlying implicit ObjectMapper instance and customizing the behavior of the new primary bean you register.

Alternatively, you can customize the Jackson2ObjectMapperBuilder that builds the ObjectMapper for your application instead of replacing the already built one. For a low-code solution - you can change the spring.jackson.default-property-inclusion property in your properties files.

Finally - you can use the @JsonInclude annotation on class-level or method-level.

Last Updated: June 14th, 2023
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

David LandupAuthor

Entrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.

Great passion for accessible education and promotion of reason, science, humanism, and progress.

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms