Spring RestTemplate消息转换器发帖时的优先级
Spring RestTemplate message converter priority when posting
影响消息转换器优先级的最方便方法是什么 Spring 适用于使用 RestTemplate
进行 POST 时?
用例:我想确保将给定的实体发布为 JSON 而不是例如XML 当我做 restTemplate.postForEntity(url, entity, Void.class)
.
默认
默认情况下,实体转换为 XML,因为 MappingJackson2XmlHttpMessageConverter
优先于 MappingJackson2HttpMessageConverter
。我的应用程序的默认转换器列表似乎是(Spring 扫描类路径以查看可用的内容):
选项 1
您可以像这样 restTemplate.setMessageConverters(Lists.newArrayList(new MappingJackson2HttpMessageConverter()))
为给定的 RestTemplate
实例显式配置消息转换器。如果实例是共享的(例如 Spring bean),这是不方便的,因为在一种情况下您可能需要转换器 X,而在另一种情况下可能需要转换器 Y。
选项 2
您可以明确设置 Accept
和 Content-Type
HTTP headers,在这种情况下 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
这可能是我要找的:)
根据 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 headers。
此问题已详细解答。
基本上,当您添加下面提到的库时,它会在 MappingJackson2HttpMessageConverter
之前添加 MappingJackson2XmlHttpMessageConverter
。因此,Spring 引导假定每个请求都接受 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;
}
影响消息转换器优先级的最方便方法是什么 Spring 适用于使用 RestTemplate
进行 POST 时?
用例:我想确保将给定的实体发布为 JSON 而不是例如XML 当我做 restTemplate.postForEntity(url, entity, Void.class)
.
默认
默认情况下,实体转换为 XML,因为 MappingJackson2XmlHttpMessageConverter
优先于 MappingJackson2HttpMessageConverter
。我的应用程序的默认转换器列表似乎是(Spring 扫描类路径以查看可用的内容):
选项 1
您可以像这样 restTemplate.setMessageConverters(Lists.newArrayList(new MappingJackson2HttpMessageConverter()))
为给定的 RestTemplate
实例显式配置消息转换器。如果实例是共享的(例如 Spring bean),这是不方便的,因为在一种情况下您可能需要转换器 X,而在另一种情况下可能需要转换器 Y。
选项 2
您可以明确设置 Accept
和 Content-Type
HTTP headers,在这种情况下 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
这可能是我要找的:)
根据 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 headers。
此问题已详细解答
基本上,当您添加下面提到的库时,它会在 MappingJackson2HttpMessageConverter
之前添加 MappingJackson2XmlHttpMessageConverter
。因此,Spring 引导假定每个请求都接受 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;
}