【问题标题】:Spring RestTemplate message converter priority when postingSpring RestTemplate 消息转换器在发布时的优先级
【发布时间】:2017-12-19 20:21:33
【问题描述】:

当使用RestTemplate POST 时,影响 Spring 应用的消息转换器优先级的最方便的方法是什么?

用例:我想确保给定实体以 JSON 形式发布,而不是例如当我做restTemplate.postForEntity(url, entity, Void.class)时的XML。

默认

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

选项 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

这可能就是我要找的:)

【问题讨论】:

    标签: java spring resttemplate


    【解决方案1】:

    这个问题详细解答here

    基本上,当您添加下面提到的库时,它会在MappingJackson2HttpMessageConverter 之前添加 MappingJackson2XmlHttpMessageConverter。因此,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;
    

    }

    【讨论】:

      【解决方案2】:

      根据 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 标头。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-11
        • 2021-05-14
        • 1970-01-01
        • 2012-05-31
        • 2020-06-24
        • 2018-01-29
        相关资源
        最近更新 更多