How to Customise the Jackson JSON Mapper Implicitly Used by Spring Boot

How to customise the Jackson JSON mapper implicitly used by Spring Boot?

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 more Jackson2ObjectMapperBuilderCustomizer 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;
}

How to configure Jackson in spring boot application without overriding springs default setting in pure java

You should use Jackson2ObjectMapperBuilderCustomizer for this

@Configuration
public class JacksonConfiguration {

@Bean
public Jackson2ObjectMapperBuilderCustomizer addCustomBigDecimalDeserialization() {
return new Jackson2ObjectMapperBuilderCustomizer() {

@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// Add your customization
// jacksonObjectMapperBuilder.featuresToEnable(...)
}
};
}
}

Because a Jackson2ObjectMapperBuilderCustomizer is a functor, Java 8 enables more compact code:

@Configuration
public class JacksonConfiguration {

@Bean
public Jackson2ObjectMapperBuilderCustomizer addCustomBigDecimalDeserialization() {
return builder -> {
builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// Add your customization
// builder.featuresToEnable(...)
};
}
}
}

Spring-Boot: Jackson serialization configuration not respected

It seems @EnableWebMvc is the culprit. I have a WebMvcConfigurer that looks like this:

@Configuration
@EnableWebMvc // <----- this is the culprit!
public class WebConfiguration implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
.allowedOrigins("example.com")
.allowedHeaders("*");
}

@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}

@Bean
public InternalResourceViewResolver defaultViewResolver() {
return new InternalResourceViewResolver();
}

}

commenting out @EnableWebMvc allows everything to work as expected.

Why is Spring Boot not using a @Primary Jackson ObjectMapper for JSON serialization on a rest controller?

Whilst the other answers show alternative ways of achieving the same result, the actual answer to this question is that I had defined a separate class that extended WebMvcConfigurationSupport. By doing that the WebMvcAutoConfiguration bean had been disabled and so the @Primary ObjectMapper was not picked up by Spring. (Look for @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) in the WebMvcAutoConfiguration source.)

Temporarily removing the class extending WebMvcConfigurationSupport allowed the @Primary ObjectMapper to be picked up and used as expected by Spring.

As I couldn't remove the WebMvcConfigurationSupport extending class permanently, I instead added the following to it:

@Autowired
private ObjectMapper mapper;

@Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter(mapper));
addDefaultHttpMessageConverters(converters);
super.configureMessageConverters(converters);
}

Spring Boot register custom jackson (polygon) deserializer after Spring Boot upgrade 2.4-2.5

I was using two @configuration annotated classes.

Fixed by adding the first config (WebConfig.class) into SpringConfig.class and registering it as a Bean;

@Configuration
public class SpringConfig {

@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}

@Bean
public WebConfig webConfig() {
return new WebConfig();
}

@Bean
public Module polygonDeserializer() {
SimpleModule module = new SimpleModule();
module.addDeserializer(Polygon.class, new PolygonDeserializer());
return module;
}
}

Second config before change;

@EnableWebMvc
@Configuration //<---- **Issue**
public class WebConfig implements WebMvcConfigurer {

...

@Override
public void addCorsMappings(CorsRegistry registry) {
...
}
}

Spring calls only one of the two config classes and does not register the custom deserializer.

Lifecycle of Jackson ObjectMapper in Spring

In general you can use Jackson2ObjectMapperBuilder and build() to generate new object mapper instance with all the recent settings applied. The default ObjectMapper is provided by JackonsObjectMapperConfiguration in JackonAutoConfiguration. All jackson2 object mapper builder instances are created by JacksonObjectMapperBuilderConfiguration in JacksonAutoConfiguration. Details on configuring object mapper can be found here

You can further customize jackson2 object mapper builder using Jackson2ObjectMapperBuilderCustomizerConfiguration if you don't like the standard defaults in JacksonAutoConfiguration

Checkout this answer - it will answer your other questions

Coming to issue - Had the same issue when using jackson2objectbuilder/build or autowiring object mapper for ser/deser annotated with JsonComponent annotation. All these annotations are scanned by JsonComponentModule bean defined in JacksonAutoConfiguration and are registered with default object mapper and all the instances created by jackson2 object mapper builder. So it is not possible to use the not built object mapper and register the ser/deser at the same time. You are right the exception ( beancurrentlyincreationexception ) is suppressed by spring and json component module is not registered with message unresolvale circular reference for object mapper.

I didn't find any solution other than creating a new object mapper outside of spring managed.



Related Topics



Leave a reply



Submit