Spring RestTemplate - 选择要使用的 MessageConverter

Posted

技术标签:

【中文标题】Spring RestTemplate - 选择要使用的 MessageConverter【英文标题】:Spring RestTemplate - selecting MessageConverter to Use 【发布时间】:2019-08-04 01:27:49 【问题描述】:

我正在使用 RestTemplate 类发布到基于 JSON 的 RESTful Web 服务。我可以从文档中看到 RestTemplate 实例可以使用多个 MessageConverters。我面临的问题是客户端似乎出于某种原因选择使用基于 XML 的转换器。 “Content-Type”标头设置为 application/XML,并且消息正文包含我想以 JSON 形式发送的对象的 XML 表示。如何最轻松地配置我的 RestTemplate 实例以使用 MappingJackson2HttpMessageConverter 处理我的请求?

【问题讨论】:

你尝试了什么? RestTemplate 顾名思义,主要用于带有 JSON 的 RESTful 请求。除非您另有配置,否则它通常会这样做。 ***.com/help/minimal-reproducible-example 我使用 RestTemplate 客户端使用相同的代码设置了一个简单的项目,并且它使用正确的有效负载和 Content-Type 标头没有问题。但是,当在具有其他连线和配置的 Spring 组件的大型项目中使用时,将使用 XML 转换器。我不确定如何弄清楚它为什么会这样。 【参考方案1】:

如果通过RestTemplateBuilder配置RestTemplate,则可以使用messageConverters(org.springframework.http.converter.HttpMessageConverter<?>... messageConverters)方法进行配置。

参考:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/client/RestTemplateBuilder.html#messageConverters-org.springframework.http.converter.HttpMessageConverter...-

【讨论】:

【参考方案2】:

您的ApplicationContext 中有多个MessageConverters。 Spring 最有可能从所有可用的消息转换器中选择Jaxb2RootElementHttpMessageConverter,从而产生 XML 输出。

要指示 Spring 在其中使用 MessageConverter,请在请求中添加内容类型标头。例如,通过执行交换而不是 get/postForEntity:

HttpHeaders headers = new HttpHeaders();
header.add("Content-Type", "application/json");

restTemplate.exchange("http://some.url", HttpMethod.GET new HttpEntity<>(headers), SomeObject.class);

或者通过将ClientHttpRequestInterceptor 附加到您的 RestTemplate (example)。当您按照示例进行操作时,请务必使用此拦截器(如教程中将 foo/bar 添加到 response 标头中):

@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException 
    httpRequest.getHeaders().set("Content-Type", "application/json");
    return clientHttpRequestExecution.execute(httpRequest, bytes);

【讨论】:

我假设正在使用 Jaxb2RootElementHttpMessageConverter(我可以通过查看一些日志语句来确认)。这是因为在类路径中找到了一些 JAXB 类吗? “默认”使用 XML 不是很奇怪吗?我正在使用组织内另一个团队编写的库,并且无法直接访问正在使用的 RestTemplate。有没有办法通过一些更高级别的 Spring 配置来解决这个问题?

以上是关于Spring RestTemplate - 选择要使用的 MessageConverter的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Commons教程Spring RestTemplate作为负载平衡器客户端

Spring RestTemplate作为负载平衡器客户端

Spring RestTemplate作为负载平衡器客户端

Spring RestTemplate作为负载平衡器客户端

Spring RestTemplate 透传Cookie

Spring RestTemplate为何必须搭配MultiValueMap?