I want to update the SerializationConfig.Feature... properties of the jackson mapper used by Spring RestTemplate, Any idea how I can get to it or where I can/should configure it.
5 Answers
The default RestTemplate
constructor 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());
}
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:
@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 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.

- 334,321
- 69
- 703
- 674
-
i would be grateful if you could translate this to XML. really want to try this but not sure how to configure it. many thanks! – Justin Feb 24 '12 at 20:24
-
11Not sure if this is just due to a version difference, but I believe the correct name for the Jackson converter class is MappingJackson*2*HttpMessageConverter – nbrooks Sep 17 '15 at 22:05
-
3I would probably avoid adding a new mappingJacksonHttpMessageConverter in the beginning of the existing default ones, but replace the existing Jackson message converter instead. Otherwise you end up having 2 Jackson message converters in the list. – mvogiatzis Feb 06 '16 at 16:34
-
I tried adding it at index 0 and I got some very strange JSON parse exceptions. Removing the existing worked better like @mvogiatzis suggested – Mads Hoel Dec 15 '17 at 12:54
-
I was need to change `RestOperations -> RestTemplate` in `@Bean` definition to make this works – chill appreciator Jun 24 '20 at 20:32
-
Shouldn't myObjectMapper() and mappingJacksonHttpMessageConverter()) be called by requesting a parameter in the @Bean methods? – borjab Dec 20 '21 at 17:31
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);

- 2,124
- 1
- 22
- 18
-
1why do you need to remove and re-add when you can just find it iterating? – lqbweb May 11 '18 at 13:32
-
1restTemplate.getMessageConverters().removeIf(m -> m.getClass().isAssignableFrom(MappingJackson2HttpMessageConverter.class)); – Rüdiger Schulz Mar 04 '19 at 11:12
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:
@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
}

- 612
- 7
- 10
-
It seems it's important to name the method something like `myObjectMapper()` but not just `objectMapper()`. For some reason it seems the method is never called and you get the default `ObjectMapper`. – herman Jun 15 '16 at 14:45
-
1This worked, but seems there is a typo in the answer? `restTemplate.getMessageConverters().set(i, mappingJackson2HttpMessageConverter);` should be `restTemplate.getMessageConverters().set(i, mappingJackson2HttpMessageConverter());` (note the parenthesis in mappingJackson2HttpMessageConverter(), making it a method call instead of a reference) – Jens Wegar Jul 12 '18 at 06:49
-
True, or you can alternatively add the `mappingJackson2HttpMessageConverter` as a parameter to the `restTemplate` function use it as is. – mvogiatzis Jul 27 '18 at 10:26
-
1you dont have to create a new one, you can just set your mapper if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter){ ((MappingJackson2HttpMessageConverter)httpMessageConverter).setObjectMapper(mapper()); } – Kalpesh Soni Mar 27 '19 at 15:30
-
In Java8 you can use streams or Java14 you can use pattern matching for instanceof. Otherwise nice declarative solution. – Andrej Buday Mar 25 '20 at 16:32
To complete the other answers: if your ObjectMapper
just registers a Jackson Module
with custom serializers/deserializers, you might want to register your module directly on the existing ObjectMapper
from RestTemplate
's default MappingJackson2HttpMessageConverter
as follows (example without DI but the same applies if 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 the configuration of the original ObjectMapper
(as done by Spring's Jackson2ObjectMapperBuilder
), instead of replacing it.

- 1,113
- 14
- 27
Using Spring Boot, it is as simple as:
RestTemplate template = new RestTemplateBuilder()
.additionalMessageConverters(new MappingJackson2HttpMessageConverter(objectMapper))
.build()
(Tested with Spring Boot 2.2.1)

- 25,113
- 20
- 133
- 211
-
With this approach your `RestTemplate` will have only one `MessageConverter`: `MappingJackson2HttpMessageConverter`. But I still like it – chill appreciator Jun 24 '20 at 20:55
-
`additionalMessageConverters` is not really additive. It will perform a full replacement and you'll loose other converters. It's stated on its docstring. (It adds to the builder's list of converters, which will fully replace the instance's) – Ming Aug 21 '20 at 19:23
-
@Ming To be more precise, `additionalMessageConverters` will not replace already configured converters on the **builder**. "Any converters configured on the builder will replace RestTemplate's default converters" means that the `RestTemplate` instance produced by `RestTemplateBuilder.build()` method will not have any other converters except those configured on the builder. So, as soon as you configure **any** `HttpMessageConverter` on the builder instance, they will replace default `RestTemplate` conveters. This could be circumvented by calling `builder.defaultMessageConverters()` first. – Ruslan Stelmachenko Jun 20 '23 at 12:53
-
Also, Spring Boot has already configured `RestTemplateBuilder` bean in `prototype` scope. This bean is already configured with default converters (the list includes all `HttpMessageConverter`s from `HttpMessageConverters` bean, that are even better than `RestTemplate`'s default). Also the bean has all `RestTemplateCustomizer` beans applied. So, you can just inject `RestTemplateBuilder` into your component and then `additionalMessageConverters` would really **add** converters, because at the moment of the calling the list would not be empty. – Ruslan Stelmachenko Jun 20 '23 at 13:01