我正在使用 RestTemplate 类发布到基于 JSON 的 RESTful Web 服务。我从文档中可以看到,RestTemplate 实例可以有多个可用的 MessageConverters。我面临的问题是客户端似乎出于某种原因选择使用基于 XML 的转换器。 “Content-Type”标头设置为 application/XML,消息正文包含我想要作为 JSON 发送的对象的 XML 表示形式。如何最轻松地配置 RestTemplate 实例以使用 MappingJackson2HttpMessageConverter 来处理我的请求?
如果您通过
RestTemplate
配置RestTemplateBuilder
,则可以使用messageConverters(org.springframework.http.converter.HttpMessageConverter<?>... messageConverters)
方法进行配置。
RestTemplateBuilder
代替 RestTemplate
:
自动配置的
确保合理的RestTemplateBuilder
应用于HttpMessageConverters
实例。RestTemplate
一旦将
jackson-dataformat-xml
添加到依赖项,RestTemplate
就开始仅使用 XML(当然,除非显式添加 (HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
),我们的应用程序中就遇到了这个问题。只需切换到 RestTemplateBuilder
就可以轻松修复。
我们通过简单地将
RestTemplate
bean 的配置更改为:
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
您的
MessageConverters
中有多个 ApplicationContext
可用。 Spring 最有可能从所有可用的消息转换器中选择 Jaxb2RootElementHttpMessageConverter
,从而生成 XML 输出。
要指示 Spring 使用哪个
MessageConverter
,请向请求添加内容类型标头。例如,通过执行交换而不是 get/postForEntity:
HttpHeaders headers = new HttpHeaders();
header.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
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(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
return clientHttpRequestExecution.execute(httpRequest, bytes);
}