How to customise the Jackson JSON mapper implicitly used by Spring Boot?
Solution 1
You can configure property inclusion, and numerous other settings, via application.properties
:
spring.jackson.default-property-inclusion=non_null
There's a table in the documentation that lists all of the properties that can be used.
If you want more control, you can also customize Spring Boot's configuration programatically using a Jackson2ObjectMapperBuilderCustomizer
bean, as described in the documentation:
The context’s
Jackson2ObjectMapperBuilder
can be customized by one or moreJackson2ObjectMapperBuilderCustomizer
beans. Such customizer beans can be ordered (Boot’s own customizer has an order of 0), letting additional customization be applied both before and after Boot’s customization.
Lastly, if you don't want any of Boot's configuration and want to take complete control over how the ObjectMapper
is configured, declare your own Jackson2ObjectMapperBuilder
bean:
@Bean
Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
// Configure the builder to suit your needs
return builder;
}
Solution 2
I am answering bit late to this question, but someone, in future, might find this useful. The below approach, besides lots of other approaches, works best, and I personally think would better suit a web application.
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
... other configurations
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
builder.propertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
builder.serializationInclusion(Include.NON_EMPTY);
builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
}
}
Solution 3
The documentation states several ways to do this.
If you want to replace the default
ObjectMapper
completely, define a@Bean
of that type and mark it as@Primary
.Defining a
@Bean
of typeJackson2ObjectMapperBuilder
will allow you to customize both defaultObjectMapper
andXmlMapper
(used inMappingJackson2HttpMessageConverter
andMappingJackson2XmlHttpMessageConverter
respectively).
Solution 4
A lot of things can configured in applicationproperties. Unfortunately this feature only in Version 1.3, but you can add in a Config-Class
@Autowired(required = true)
public void configureJackson(ObjectMapper jackson2ObjectMapper) {
jackson2ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
[UPDATE: You must work on the ObjectMapper because the build()
-method is called before the config is runs.]
Solution 5
You can add a following method inside your bootstrap class which is annotated with @SpringBootApplication
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
objectMapper.registerModule(new JodaModule());
return objectMapper;
}
Related videos on Youtube
Jonik
I'm a generalist software developer who's been programming professionally for 15+ years. Simplicity, code maintainability, easy deployments, automated testing, and continuous integration are some of the things close to my heart as a developer. I currently work as a freelance developer, focused on backend (Java/Scala/JVM mostly) and Android development. Enjoying Kotlin and Jetpack Compose nowadays especially! You can reach me by email through <jonik at iki dot country code for finland>.
Updated on March 10, 2022Comments
-
Jonik about 2 years
I'm using Spring Boot (1.2.1), in a similar fashion as in their Building a RESTful Web Service tutorial:
@RestController public class EventController { @RequestMapping("/events/all") EventList events() { return proxyService.getAllEvents(); } }
So above, Spring MVC implicitly uses Jackson for serialising my
EventList
object into JSON.But I want to do some simple customisations to the JSON format, such as:
setSerializationInclusion(JsonInclude.Include.NON_NULL)
Question is, what is the simplest way to customise the implicit JSON mapper?
I tried the approach in this blog post, creating a CustomObjectMapper and so on, but the step 3, "Register classes in the Spring context", fails:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jacksonFix': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.acme.project.JacksonFix.setAnnotationMethodHandlerAdapter(org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
It looks like those instructions are for older versions of Spring MVC, while I'm looking for a simple way to get this working with latest Spring Boot.
-
sven.kwiotek over 9 yearsDo you have this Annotation inserted?: @SuppressWarnings({"SpringJavaAutowiringInspection"})
-
Constantino Cronemberger about 5 yearsNotice that if you are using Spring Web as well you will need to tell it manually to use this ObjectMapper otherwise it will create it own instance which will not be configured. See stackoverflow.com/questions/7854030/…
-
-
Jonik over 9 yearsAlright, this seems to work. Where would you put such a method? Perhaps in a main Application class (with
@ComponentScan
,@EnableAutoConfiguration
etc)? -
Andy Wilkinson over 9 yearsYes. This method can go in any
@Configuration
class in your app. The mainApplication
class is a good place for it. -
Andy Wilkinson over 9 yearsThe downside to this approach is that your custom configuration won't be applied to any
ObjectMapper
instances that are created or configured by Spring Boot. -
Jonik over 9 yearsHmm, the custom config is used for the implicit serialisation in
@RestController
classes which currently suffices for me. (So you mean those instances are created by Spring MVC, not Spring Boot?) But if I run into other cases where ObjectMappers need to be instantiated, I'll keep the Jackson2ObjectMapperBuilder approach in mind! -
gaoagong almost 9 yearsImportant note: The Jackson2ObjectMapperBuilder class is part of the spring-web component and was added in version 4.1.1.
-
herau over 8 years@AndyWilkinson With this configuration, you can't use anymore Spring boot auto-configuration for Jackson isn't it ?
-
Andy Wilkinson over 8 years@herau Correct. If you're happy using a milestone, Spring Boot 1.3 adds support for configuring serialisation inclusion via application.properties: github.com/spring-projects/spring-boot/commit/…
-
Dimitri Kopriwa almost 8 years@Deprecated setSerializationInclusion
-
so-random-dude almost 7 yearsDeprecated: ObjectMapper.setSerializationInclusion was deprecated in Jackson 2.7 ... use stackoverflow.com/a/44137972/6785908 spring.jackson.default-property-inclusion=non_null instead
-
Nestor Milyaev over 6 yearsThat was the solution that saved my day. Except I did add this method to the REST controller itself, rather than to the configuration class.
-
GuiRitter about 6 years"If you're using an earlier version of Spring Boot" made me believe it wouldn't work with Spring Boot 2.0.1, but it worked. Thanks!
-
soufrk almost 6 yearsHow to do the same without replacing the default
ObjectMapper
? I mean keeping the default as well a custom. -
Richtopia about 5 yearsThis one worked for me using Boot 2.1.3. The spring.jackson properties had no effect.
-
João Pedro Schmitt over 4 yearsIn recent version you must implement
WebMvcConfigurer
-
Somal Somalski almost 4 yearsyes, peoples, try this solution, I've tried to provide Bean for ObjectMapper, then Bean for Jackson2ObjectMapperBuilder buy that didn't work and I still have no idea why. Appending coverter worked!
-
Michael over 3 yearsI am having a problem with this approach of configuring the ObjectMapper in Spring Boot. Spring Boot does its own configuration of the ObjectMapper with its own Serializers/Deserializers for e.g. LocalDateTime. When defining your own Jackson2ObjectMapperBuilder you are loosing this Spring configuration.
-
M. Justin over 3 yearsThere are more properties than just the six mentioned in the linked "How-to" guide. A full list is available a the reference documentation appendex (currently eleven
spring.jackson.*
options are mentioned).