Spring Boot – Customize the Jackson ObjectMapper

07 Feb, 2022
When using JSON format, Spring Boot will use an ObjectMapper instance to serialize responses and deserialize requests. In this article, we will take a look at the most common ways to configure the serialization and deserialization options.
Let us do go through the default configuration. So by default, the Spring Boot configuration will be as follows:
Disable MapperFeature.DEFAULT_VIEW_INCLUSION
Disable DeserializationFeature. FAIL_ON_UNKNOWN_PROPERTIES
Disable SerializationFeature. WRITE_DATES_AS_TIMESTAMPS
Let’s start with a quicker example by implementing the same
Implementation: 
The client sends a GET request to our/coffee?name=Lavazza
The controller will return a new Coffee object
Spring will use customization options by using String and LocalDateTime objects
It is as follows, so primarily we need to create a class named Coffee which is as follows:
// Class
public class Coffee {

  // Getters and setters
  private String name;
  private String brand;
  private LocalDateTime date;
}
Now we will also be defining a simple REST controller to demonstrate the serialization:
@GetMapping ("/coffee")

public Coffee getCoffee(
  @RequestParam(required =  false) String brand,
  @RequiredParam(required = false) String name) {

  return new Coffee()
         .setBrand(brand)
         .setDate(FIXED_DATE)
         .setName(name);
}
By default, the response when calling GET http://localhost:8080/cofffee?brand=lavazza will be as follows:
{
  "name": null,
  "brand": Lavazza",
  "date": "2020 - 11 - 16T10: 21: 35.974"
}
Now We would like to exclude null values and to have a custom date format (dd-MM-yyy HH:mm). The final response will be as follows:
{
  "brand:" "Lavazza",
  "date": "04-11-20202 10:34"
}
When using Spring Boot, we have the option to customize the default ObjectMapper or to override it. We’ll cover both of these options in the next sections.
Now let us roll to eccentric point in article by customizing the Default Object Mapper. Here. we will be discussing how to customize the default ObjectMapper that Spring Boot uses.
Application Properties and Custom Jackson Module
The simplest way to configure the mapper is via application properties.  The general structure of the configuration is as follows:
  spring.jackson.<category_name>.<feature_name>=true, false
As an example, if we want to disable SerializationFeature. WRITE_DATES_AS_TIMESTAMPS, we’ll add:
spring.jackson.serialization.write-dates-as-timestamps=false
Besides the mentioned feature categories, we can also configure property inclusion:
spring.jackson.default-property-inclusion=always, non_null, non_absent, non_default, non_empty
Configuring the environment variables in the simplest approach. The downside of this approach is that we can’t customize advanced options like having a custom date format for LocalDateTime. At this point, we’ll obtain the result which is shown below:
{
  "brand": "Lavazza",
  "date": "2020-11-16T10:35:34.593"
}
Now in order to achieve our goal, we’ll register a new JavaTimeModule with our custom date format:
@Configuration
@PropertySource("classpath:coffee.properties")

// Class
public class CoffeeRegisterModuleConfig {

  @Bean

  public Module javaTimeModule() {

    JavaTimeModule module = new JavaTimeModule();
    module.addSerializer(LOCAL_DATETIME_SERIALIZER);

    return module;
  }
}
Jackson2ObjectMapperBuilderCustomizer
The purpose of this functional interface is to allow us to create configuration beans. They will be applied to the default ObjectMapper created via Jackson2ObjectMapperBuilder.
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
  return builder ->
         builder.serializationInclusion(JsonInclude.Include.NON_NULL)
         .serializers(LOCAL_DATETIME_SERIALIZER);
}
The configuration beans are applied in a specific order, which we can control using the @Order annotations. This elegant approach is suitable if we want to configure the ObjectMapper from different configurations or modules.
Jackson2ObjectMapperBuilder
Another clean approach is to define a Jackson2ObjectMapperBuilder bean. Actually, Spring Boot is using this builder by default when building the ObjectMapper and will automatically pick up the defined one:
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
  return new
         Jackson2ObjectMapperBuilder().serializers(LOCAL_DATETIME_SERIALIZER)
         .serializationInclusion(JsonInclude.Include.NON_NULL);
}
It will configure two options by default:
Disable MapperFeature.DEFAULT_VIEW_INCLUSION
Disable DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
According to the Jackson2ObjectMapperBuilder documentation, it will also register some modules if they’re present on the classpath:
jackson-datatype-jdk8:support for other Java 8 types like Optional
jackson-datatype-jsr310:support for Java 8 Date and Time API types
jackson-datatype-joda:support for Joda-Time types
jackson-module-kotlin:support for Kotlin classes and data classes
Note: The advantage of this approach is that the Jackson2ObjectMapperBuilder offers a simple and intuitive way to build an ObjectMapper.
We can just define a bean with the type MappingJackson2HttpMessageConverter, and Spring Boot will automatically use it:
@Bean

// Convertor method
public MappingJackson2HttpMessageConverter() {

  Jackson2ObjectMapperBuilder builder = new
  Jackson2ObjectMapperBuilder().serializers(LOCAL_DATE_SERIALIZER)
  .serializationInclusion(JsonInclude.Include.NON_NULL);

  return new MappingJackson2HttpMessageConverter(builder.build());
}
Note: Make sure to check out our Spring Http Message Converters article to learn more.
Testing the Configuration
Lastly, in order to test our configuration, we’ll use TestRestTemplate and serialize the objects as String. In this way, we can validate that our Coffee object is serialized without null values and with the custom date format:
@Test

public void whenGetCoffee_thenSerializedWithDateAndNonNull() {

  String formattedDate =
    DateTimeFormatter.ofPattern(CoffeeConstants.dateTimeFormat).format(FIXED_DATE);

// Our strings
  String brand = "Lavazza";
  String url = "/coffee?branf=" + brand;
  String response = restTemplate.getForObject(url, String.class);

  assertThat(response).isEqualTo("{"brand\":\"" + brand +
                                "\",\"date\":\"" + formatedDate + "\"}");
}
Conclusion: We took a look at several methods to configure the JSON serialization options when using Spring Boot. Here we saw two different approaches:configuring the default options or overriding the default configuration.
manikarora059
anikaseth98
singghakshay
adnanirshad158
sagar0719kumar
sumitgumber28
Java-Spring-Boot
Java
Java
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Object Oriented Programming (OOPs) Concept in Java
How to iterate any Map in Java
Interfaces in Java
HashMap in Java with Examples
ArrayList in Java
Stream In Java
Collections in Java
Multidimensional Arrays in Java
Singleton Class in Java
Set in Java