4 ответов:
по умолчанию
RestTemplateконструктор регистрирует набор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в свою очередь, создает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подход я мог ссылайтесь на существующий и просто измените его. Но это должно сработать.
Если вы не используете 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);
RestTemplate инициализирует свои конвертеры сообщений по умолчанию. Вы должны заменить
MappingJackson2HttpMessageConverterС вашим собственным Бобом, который должен использовать объект mapper, который вы хотите использовать. Это сработало для меня:@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 }
чтобы завершить другие ответы: если ваш
ObjectMapperпросто регистрирует Джексон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), вместо того, чтобы заменить его.
Comments