【发布时间】:2010-07-23 21:09:37
【问题描述】:
好的,我有一个 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 以及它的集合是否为空。如果是这样,我将状态代码设置为 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 的情况下解决这个问题?我是否错误地看待这种情况?请帮忙,因为我有点困惑。
【问题讨论】:
-
我现在正在处理这个问题。你有没有想出任何解决方案?
-
并非如此。这对我们来说不是一个大问题,因为我们只在 junits 中使用 RestTemplate,所以我们只需将类设置为 null。看起来下面的答案可能会帮助你。您应该对下面的 spring jira 增强请求进行投票。
-
我或多或少在同一条船上,使用 RestTemplate 进行单元测试。没什么大不了的,但我肯定会投票支持这项改进。
标签: java web-services unit-testing rest spring-mvc