发布时Spring RestTemplate消息转换器优先级

时间:2017-12-19 20:21:34

标签: java spring resttemplate

影响邮件转换器优先级的最方便方法是什么时候使用RestTemplate进行POST时应用Spring?

用例:我想确保将给定实体作为JSON进行POST,而不是例如我做restTemplate.postForEntity(url, entity, Void.class)时的XML。

默认

默认情况下,实体会转换为XML,因为MappingJackson2XmlHttpMessageConverter优先于MappingJackson2HttpMessageConverter。我的应用程序的默认转换器列表似乎是(Spring扫描类路径以查看可用的内容): enter image description here

选项1

您可以为给定的RestTemplate实例明确配置消息转换器,如restTemplate.setMessageConverters(Lists.newArrayList(new MappingJackson2HttpMessageConverter()))。如果实例是共享的(例如Spring bean),这是不方便的,因为在一种情况下可能需要转换器X而在另一种情况下需要转换器Y.

选项2

您可以明确设置AcceptContent-Type HTTP标头,在这种情况下,Spring将使用匹配的消息转换器。缺点是您必须使用RestTemplate.exchange而不是RestTemplate.postForEntity,这意味着:额外的代码,更少的便利。

HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
HttpEntity requestEntity = new HttpEntity(entity, requestHeaders);
restTemplate.exchange(url, HttpMethod.POST, requestEntity, Void.class);

选项3

这可能是我正在寻找的东西:)

2 个答案:

答案 0 :(得分:0)

根据Spring javadoc(https://docs.spring.io/spring-framework/docs/current/javadoc-api/index.html?org/springframework/web/client/RestTemplate.html)你仍然可以使用postForEntity,

public <T> ResponseEntity<T> postForEntity(java.lang.String url,
                                       @Nullable
                                       java.lang.Object request,
                                       java.lang.Class<T> responseType,
                                       java.util.Map<java.lang.String,?> uriVariables)
                                throws RestClientException
....

request参数可以是HttpEntity,以便为请求添加其他HTTP标头。

答案 1 :(得分:0)

此问题已详细解答here

基本上,当您添加下面提到的库时,它会在 MappingJackson2XmlHttpMessageConverter 之前添加 MappingJackson2HttpMessageConverter。因此,Spring Boot 假设每个请求都接受 application/XML

 <dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

为了避免这种行为,您可能需要交换两个消息转换器。

示例:

  @Bean
RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
// move XML converter to the end of list
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
for (int i = 0; i < messageConverters.size() -1 ; i++) {
    if (messageConverters.get(i) instanceof MappingJackson2XmlHttpMessageConverter) {
        Collections.swap(messageConverters, i,messageConverters.size() - 1);
    }
}

restTemplate.setMessageConverters(messageConverters);

// add interceptors if necessary
restTemplate.setInterceptors(Collections.singletonList(catalogInterceptior()));
return restTemplate;

}