Как мы можем настроить внутренний картограф Джексона при использовании RestTemplate? - PullRequest
65 голосов
/ 21 февраля 2012

Я хочу обновить свойства SerializationConfig.Feature ... картографа Джексона, используемого Spring RestTemplate. Любая идея, как мне к нему добраться или где я могу / должен его настроить.

Ответы [ 4 ]

83 голосов
/ 21 февраля 2012

Конструктор RestTemplate по умолчанию регистрирует набор 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 по очереди создает непосредственно экземпляр ObjectMapper.Вы можете найти этот конвертер и заменить ObjectMapper или зарегистрировать новый перед ним.Это должно работать:

@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
}

В XML это что-то вроде этого:

<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"/>

Обратите внимание, что переход на самом деле не 1: 1 - я должен явно создать messageConverters список в XML, в то время как с @Configuration подходом я мог бы сослаться на существующий и просто изменить его.Но это должно сработать.

21 голосов
/ 10 июля 2016

Если вы не используете Spring IOC, вы можете сделать что-то вроде этого (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);
10 голосов
/ 06 февраля 2016

RestTemplate инициализирует конвертеры сообщений по умолчанию.Вы должны заменить MappingJackson2HttpMessageConverter своим собственным компонентом, который должен использовать объектный преобразователь, который вы хотите использовать.Это сработало для меня:

@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
}
6 голосов
/ 08 ноября 2017

Чтобы завершить другие ответы: если ваш ObjectMapper просто регистрирует Jackson Module с пользовательскими сериализаторами / десериализаторами, вы можете зарегистрировать свой модуль непосредственно на существующем ObjectMapper с RestTemplate по умолчанию MappingJackson2HttpMessageConverter следующим образом (пример без DI, но то же самое применимо при использовании 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);

Это позволит вам завершить настройку исходного ObjectMapper (как это было сделано в Jackson2ObjectMapperBuilder Spring) вместо его замены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...