处理状态为 NO_CONTENT 的响应时的 Spring RestTemplate 行为 [英] Spring RestTemplate Behavior when handling responses with a status of NO_CONTENT

查看:27
本文介绍了处理状态为 NO_CONTENT 的响应时的 Spring RestTemplate 行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我有一个 NamedSystems 类,它的唯一字段是一个 NamedSystem 集.

Okay, I have a class NamedSystems, that has as its only field a Set of NamedSystem.

我有一种方法可以根据特定条件查找 NamedSystems.这并不重要.当它得到结果时,一切正常.但是,当它找不到任何东西并因此返回一个空(或空——我两种方法都试过)集时,我就会遇到问题.让我解释一下.

I have a method to find NamedSystems by certain criteria. That's not really important. When it gets results, everything works fine. However, when it can't find anything, and thus returns a null (or empty -- I've tried both ways) set, I get problems. Let me explain.

我正在使用 Spring RestTemplate 类,并且正在单元测试中进行这样的调用:

I'm using the Spring RestTemplate class and I'm making a call like this in a 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).

Now, since this would normally return a 200, but I want to return a 204, I have an interceptor in my service that determines if a ModelAndView is a NamedSystem and if its set is null. If so, I then the set the status code to NO_CONTENT (204).

当我运行 junit 测试时,出现此错误:

When I run my junit test, I get this error:

org.springframework.web.client.RestClientException: Cannot extract response: no Content-Type found

将状态设置为 NO_CONTENT 似乎会擦除内容类型字段(当我考虑时这确实有意义).那么它为什么还要看它呢?

Setting the status to NO_CONTENT seems to wipe the content-type field (which does make sense when I think about it). So why is it even looking at it?

Spring 的 HttpMessageConverterExtractor 的提取数据方法:

Spring's HttpMessageConverterExtractor extractData method:

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() 方法:

Going up the chain a bit to find out where that Extractor is set, I come to RestTemplate's exchange() method that I used in the test:

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,它也能正常执行.

So, it's trying to convert what amounts to nothing because of the supplied response type from the exchange call. If I change the responseType from NamedSystems.class to null, it works as expected. It doesn't try to convert anything. If I had tried to set the status code to 404, it also executes fine.

我是否被误导了,或者这看起来像是 RestTemplate 中的一个缺陷?当然,我现在正在使用 junit,所以我知道会发生什么,但是如果有人使用 RestTemplate 调用它并且不知道服务调用的结果,他们自然会将 NamedSystems 作为响应类型.但是,如果他们尝试使用没有任何元素的条件搜索,就会出现这个令人讨厌的错误.

Am I misguided, or does this seem like a flaw in RestTemplate? Sure, I'm using a junit right now so I know what's going to happen, but if someone is using RestTemplate to call this and doesn't know the outcome of the service call, they would naturally have NamedSystems as a response type. However, if they tried a criteria search that came up with no elements, they'd have this nasty error.

有没有办法在不覆盖任何 RestTemplate 的情况下解决这个问题?我是否错误地看待这种情况?请帮助,因为我有点困惑.

Is there a way around this without overriding any RestTemplate stuff? Am I viewing this situation incorrectly? Please help as I'm a bit baffled.

推荐答案

现在应该在 Spring 3.1 RC1 中修复此问题.

This should now be fixed in Spring 3.1 RC1.

https://jira.spring.io/browse/SPR-7911

这篇关于处理状态为 NO_CONTENT 的响应时的 Spring RestTemplate 行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆