How can we configure the internal Jackson mapper when using RestTemplate? How can we configure the internal Jackson mapper when using RestTemplate? spring spring

How can we configure the internal Jackson mapper when using RestTemplate?


The default RestTemplate constructor registers a set of HttpMessageConverters:

this.messageConverters.add(new ByteArrayHttpMessageConverter());this.messageConverters.add(new StringHttpMessageConverter());this.messageConverters.add(new ResourceHttpMessageConverter());this.messageConverters.add(new SourceHttpMessageConverter());this.messageConverters.add(new XmlAwareFormHttpMessageConverter());if (jaxb2Present) {    this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());}if (jacksonPresent) {    this.messageConverters.add(new MappingJacksonHttpMessageConverter());}if (romePresent) {    this.messageConverters.add(new AtomFeedHttpMessageConverter());    this.messageConverters.add(new RssChannelHttpMessageConverter());}

The MappingJacksonHttpMessageConverter in turns, creates ObjectMapper instance directly. You can either find this converter and replace ObjectMapper or register a new one before it. This should work:

@Beanpublic RestOperations restOperations() {    RestTemplate rest = new RestTemplate();    //this is crucial!    rest.getMessageConverters().add(0, mappingJacksonHttpMessageConverter());    return rest;}@Beanpublic MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter() {    MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();    converter.setObjectMapper(myObjectMapper());    return converter;}@Beanpublic ObjectMapper myObjectMapper() {    //your custom ObjectMapper here}

In XML it is something along these lines:

<bean id="restOperations" class="org.springframework.web.client.RestTemplate">    <property name="messageConverters">        <util:list>            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>            <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>            <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>            <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">                <property name="objectMapper" ref="customObjectMapper"/>            </bean>        </util:list>    </property></bean><bean id="customObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"/>

Note that the transition isn't really 1:1 - I have to explicitly create messageConverters list in XML while with @Configuration approach I could reference existing one and simply modify it. But this should work.


If you are not using Spring IOC, you can do something like this (Java 8):

ObjectMapper objectMapper = new ObjectMapper();// configure your ObjectMapper hereRestTemplate restTemplate = new RestTemplate();    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();messageConverter.setPrettyPrint(false);messageConverter.setObjectMapper(objectMapper);restTemplate.getMessageConverters().removeIf(m -> m.getClass().getName().equals(MappingJackson2HttpMessageConverter.class.getName()));restTemplate.getMessageConverters().add(messageConverter);


RestTemplate will initialize its default message converters. You should replace the MappingJackson2HttpMessageConverter with your own bean, which should use the object mapper you want to use. This worked for me:

@Beanpublic RestTemplate restTemplate() {    final RestTemplate restTemplate = new RestTemplate();    //find and replace Jackson message converter with our own    for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) {        final HttpMessageConverter<?> httpMessageConverter = restTemplate.getMessageConverters().get(i);        if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter){            restTemplate.getMessageConverters().set(i, mappingJackson2HttpMessageConverter());        }    }    return restTemplate;}@Beanpublic MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();    converter.setObjectMapper(myObjectMapper());    return converter;}@Beanpublic ObjectMapper myObjectMapper() {    // return your own object mapper}