Хорошо, у меня есть класс NamedSystems, у которого в качестве единственного поля есть Set of NamedSystem.
У меня есть метод поиска NamedSystems по определенным критериям. Это не очень важно. Когда он получает результаты, все работает нормально. Однако, когда он ничего не может найти и, таким образом, возвращает нулевой (или пустой - я попытался в обоих направлениях), у меня возникают проблемы. Позвольте мне объяснить.
Я использую класс Spring RestTemplate, и я делаю такой вызов в unit test:
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 + "]");
}
Поднимая цепочку немного, чтобы узнать, где установлен этот 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? Я рассматриваю эту ситуацию неправильно? Пожалуйста, помогите, поскольку я немного озадачен.