How to change the default objectMapper of MappingJacksonHttpMessageConverter?

java, spring, spring-mvc

Solution

You can do it through code, without having to declare the `RequestMappingHandlerAdapter` bean and manually initialize all of those converters. You should write a `BeanPostProcessor`, like so:

public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof AnnotationMethodHandlerAdapter) {
            AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) bean;
            HttpMessageConverter<?>[] converters = adapter.getMessageConverters();

            for (HttpMessageConverter<?> converter : converters) {
                if (converter instanceof MappingJacksonHttpMessageConverter) {
                    initConverter((MappingJacksonHttpMessageConverter) converter);
                }
            }
        } else  if(bean instanceof MappingJacksonHttpMessageConverter){
            initConverter((MappingJacksonHttpMessageConverter) bean);
        }
        return bean;
    }

    private void initConverter(MappingJacksonHttpMessageConverter converter) {
            MappingJacksonHttpMessageConverter jsonConverter = (MappingJacksonHttpMessageConverter) converter;
            final ObjectMapper mapper = // get your mapper from wherever
            jsonConverter.setObjectMapper(mapper);

            /* here you can apply any other configuration you wish*/
     }
}

And define it as a bean:

<bean class="my.package.MyBeanPostProcessor" id="myBeanPostProcessor" lazy-init="false"/>

This way you edit exactly what actually interests you - the `MappingJacksonHttpMessageConverter`.

Problem

I would like to replace the default objectMapper of the MappingJacksonHttpMessageConverter. I found a working solution but I am not happy about it: ``` <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> <!-- Scans the classpath of this application for @Components to deploy as beans --> <context:component-scan base-package="org.mypackage.service"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <!--Adding the default message converters--> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="writeAcceptCharset" value="false"/> </bean> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/> <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/> <!--Adding our custom JSON converter--> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="objectMapper"> <util:constant static-field="org.mypackage.JsonUtils.MAPPER"/> </property> </bean> </list> </property> </bean> ``` The solution initializes RequestMappingHandlerAdapter classes with my custom list of message converters. I don't like this solution because I needed to add the default message converters (which I copied from the `org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter` constructor). Without adding the default converters - my controllers could handle only application/json requests and forgot how to handle other basic requests such as application/xml. Thanks.

Original source