Spring RestTemplate处理状态为NO_CONTENT的响应时的行为
问题内容:
好的,我有一个NamedSystems类,该类的唯一字段是NamedSystem集。
我有一种方法可以通过某些条件查找NamedSystems。那不是很重要。当得到结果时,一切正常。但是,当它找不到任何东西并因此返回null(或为空-
我已经尝试过两种方法)时,就会遇到问题。让我解释。
我正在使用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以及其set是否为null。如果是这样,则将状态代码设置为NO_CONTENT(204)。
当我运行junit测试时,出现以下错误:
org.springframework.web.client.RestClientException: Cannot extract response: no Content-Type found
将状态设置为NO_CONTENT似乎会擦除content-type字段(考虑到这一点确实很有意义)。那么为什么还要看呢?
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 + "]");
}
稍微向上看一下链,以找出在哪里设置了Extractor,我来看看我在测试中使用的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东西?我是否错误地看待这种情况?请帮忙,因为我有点困惑。
问题答案: