2012-02-21 171 views

回答

64

默认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 - 我要明确地建立在XML messageConverters列表,同时用@Configuration方法我可以参考现有的并简单地修改它。但这应该工作。

+0

如果你能把它翻译成XML,我将不胜感激。真的想试试这个,但不知道如何配置它。非常感谢! – Justin 2012-02-24 20:24:13

+2

@Justin:做我的客人 - 看到更新的答案。 – 2012-02-24 21:32:09

+4

不知道这是否仅仅是由于版本差异,但我相信杰克逊转换器类的正确名称是MappingJackson * 2 * HttpMessageConverter – nbrooks 2015-09-17 22:05:24

3

RestTemplate将初始化其默认消息转换器。你应该用你自己的bean代替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 
} 
+0

似乎命名方法类似于'myObjectMapper()'而不仅仅是'objectMapper()'是很重要的。出于某种原因,它似乎永远不会调用该方法,并且您将获得默认的“ObjectMapper”。 – herman 2016-06-15 14:45:03

18

如果不使用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); 
1

要完成其他答案:如果你ObjectMapper只是注册了一个杰克逊Module自定义串行/解串器,您可能要对现有ObjectMapperRestTemplate的默认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(由Spring的Jackson2ObjectMapperBuilder完成)的配置,而不是替换它。