Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to customise Jackson in Spring Boot 1.4

I've been unable to find examples of how to use Jackson2ObjectMapperBuilderCustomizer.java in spring boot 1.4 to customise the features of Jackson.

The doco for customising Jackson in boot 1.4 - https://docs.spring.io/spring-boot/docs/1.4.x/reference/htmlsingle/#howto-customize-the-jackson-objectmapper

My configuration works, although I am unsure if this is the correct way to customise the object mapper using Jackson2ObjectMapperBuilderCustomizer.java

@Configuration
public class JacksonAutoConfiguration {

    @Autowired
    private Environment env;

    @Bean
    public Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(
        List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
        Jackson2ObjectMapperBuilder builder = configureObjectMapper();
        customize(builder, customizers);
        return builder;
    }

    private void customize(Jackson2ObjectMapperBuilder builder,
                           List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
        for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
            customizer.customize(builder);
        }
    }

    private Jackson2ObjectMapperBuilder configureObjectMapper() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        List<String> activeProfiles = asList(env.getActiveProfiles());
        if (activeProfiles.contains(SPRING_PROFILE_DEVELOPMENT)) {
            builder.featuresToEnable(SerializationFeature.INDENT_OUTPUT);
        }
        return builder;
    }
}

To provide some context, this class sits in my own spring starter project for REST services that just auto configures a number of things, like ControllerAdvice and some trivial features like the above.

So my goal is to extend the Jackson configuration rather than to override any configuration provided by boot or other packages.

like image 362
Reece Avatar asked Sep 01 '16 05:09

Reece


2 Answers

To customize the Jackson ObjectMapper that's already pre-configured by Spring Boot, I was able to do this (the example here is to add a custom deserializer).

Configuration class:

@SpringBootConfiguration
public class Application {

    @Autowired
    private BigDecimalDeserializer bigDecimalDeserializer;

    ...

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

            @Override
            public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
                jacksonObjectMapperBuilder.deserializerByType(BigDecimal.class, bigDecimalDeserializer);
            }

        };
    }

    ...

}

And my custom deserializer, to show how it's picked up by Spring:

@Component
public class BigDecimalDeserializer extends StdDeserializer<BigDecimal> {

    public BigDecimalDeserializer() {
        super(BigDecimal.class);
    }

    @Override
    public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        ...
    }

    ...

}
like image 101
Mark Avatar answered Oct 11 '22 20:10

Mark


It depends on what you're trying to do.

If you want to make some customisations in addition to those that are performed by default then you should create your own Jackson2ObjectMapperBuilderCustomizer implementation and expose it as a bean. What you currently have is a more complex version of this. Rather than having the customisers injected and then calling them yourself, you can just create your own customiser bean and Boot will call it for you.

If you want to take complete control and switch off all of Boot's customisations then create a Jackson2ObjectMapperBuilder or ObjectMapper bean and configure it as required. The builder approach is preferred as this builder is then also used to configure ObjectMappers created by other components such as Spring Data REST.

Looking at your code and taking a step back, you could configure things far more simply by using a profile-specific configuration file (something like application-dev.properties) to enable indenting of Jackson's output. You can read more about that here.

like image 9
Andy Wilkinson Avatar answered Oct 11 '22 22:10

Andy Wilkinson