处理状态为 NO_CONTENT 的响应时的 Spring RestTemplate 行为
好的,我有一个类NameEdSystems,它的唯一字段是NameEdSystem的集合。
我有一种方法可以根据某些标准找到命名系统。这并不重要。当它得到结果时,一切正常。但是,当它找不到任何东西,因此返回一个空(或空 - 我已经尝试过两种方式)集时,我遇到了问题。让我解释一下。
我正在使用Spring RestTemplate类,并在单元测试中进行这样的调用:
ResponseEntity<?> responseEntity = template.exchange(BASE_SERVICE_URL + "?
alias={aliasValue}&aliasAuthority={aliasAssigningAuthority}",
HttpMethod.GET, makeHttpEntity("xml"), NamedSystems.class,
alias1.getAlias(), alias1.getAuthority());
现在,由于这通常会返回 200,但我想返回 204,因此我的服务中有一个侦听器,用于确定 ModelAndView 是否为 NamedSystem,以及其集合是否为 null。如果是这样,我将状态代码设置为NO_CONTENT(204)。
当我运行我的 junit 测试时,我收到此错误:
org.springframework.web.client.RestClientException: Cannot extract response: no Content-Type found
将状态设置为NO_CONTENT似乎会擦除内容类型字段(当我想到它时,这确实有意义)。那么,为什么它甚至会看着它呢?
Spring的HttpMessageConverterExtractor extractData方法:
public T extractData(ClientHttpResponse response) throws IOException {
MediaType contentType = response.getHeaders().getContentType();
if (contentType == null) {
throw new RestClientException("Cannot extract response: no Content-Type found");
}
for (HttpMessageConverter messageConverter : messageConverters) {
if (messageConverter.canRead(responseType, contentType)) {
if (logger.isDebugEnabled()) {
logger.debug("Reading [" + responseType.getName() + "] as \"" + contentType
+"\" using [" + messageConverter + "]");
}
return (T) messageConverter.read(this.responseType, response);
}
}
throw new RestClientException(
"Could not extract response: no suitable HttpMessageConverter found for response type [" +
this.responseType.getName() + "] and content type [" + contentType + "]");
}
沿着链向上走一点,找出提取器的设置位置,我来到了我在测试中使用的RestTemplate的exchange()方法:
public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException {
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(requestEntity, responseType);
ResponseEntityResponseExtractor<T> responseExtractor = new ResponseEntityResponseExtractor<T>(responseType);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
因此,它正在尝试将相当于无的内容转换为无,因为从交换调用中提供了响应类型。如果我将 responseType 从 NamedSystems.class 更改为 null,它将按预期工作。它不会尝试转换任何内容。如果我尝试将状态代码设置为404,它也执行正常。
我是被误导了,还是这似乎是RestTemplate中的一个缺陷?当然,我现在正在使用junit,所以我知道会发生什么,但是如果有人使用RestTemplate来调用它并且不知道服务调用的结果,他们自然会将NamedSystems作为响应类型。但是,如果他们尝试了没有元素的标准搜索,他们就会遇到这个令人讨厌的错误。
有没有办法在不覆盖任何RestTemplate内容的情况下解决这个问题?我是否错误地查看了这种情况?请帮忙,因为我有点困惑。