How can we configure Jackson's internal mapper when using RestTemplate?

I want to update the SerializationConfig.Feature ... properties that are used by Spring RestTemplate, any idea how I can get to it or where I can / should configure it.

+42
spring jackson
Feb 21 '12 at 16:56
source share
4 answers

The RestTemplate constructor by default registers a set of HttpMessageConverter s:

 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()); } 

MappingJacksonHttpMessageConverter turns instantiating an ObjectMapper directly. You can find this converter and replace ObjectMapper or register a new one. This should work:

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

In XML, it's something like that:

 <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 is not really 1: 1 - I have to explicitly create a list of messageConverters in XML, and with the @Configuration approach @Configuration I could reference an existing one and just modify it. But that should work.

+61
Feb 21 '12 at 17:06
source share

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

 ObjectMapper objectMapper = new ObjectMapper(); // configure your ObjectMapper here RestTemplate 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); 
+13
Jul 09 '16 at 21:01
source share

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

 @Bean public 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; } @Bean public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(myObjectMapper()); return converter; } @Bean public ObjectMapper myObjectMapper() { // return your own object mapper } 
+3
Feb 06 '16 at 16:34
source share

To fulfill other answers: if your ObjectMapper simply registers the Jackson Module using custom serializers / deserializers, you might want to register your module directly in the existing ObjectMapper from RestTemplate 's default MappingJackson2HttpMessageConverter as (example without DI, but the same applies when using DI) :

  SimpleModule module = new SimpleModule(); module.addSerializer(...); module.addDeserializer(...); MappingJackson2HttpMessageConverter messageConverter = restTemplate.getMessageConverters().stream() .filter(MappingJackson2HttpMessageConverter.class::isInstance) .map(MappingJackson2HttpMessageConverter.class::cast) .findFirst().orElseThrow( () -> new RuntimeException("MappingJackson2HttpMessageConverter not found")); messageConverter.getObjectMapper().registerModule(module); 

This will allow you to complete customizing the original ObjectMapper (as done with Spring Jackson2ObjectMapperBuilder ) instead of replacing it.

+1
Nov 08 '17 at 10:07 on
source share



All Articles