RestTemplate ClientHttpResponse.getBody() 抛出 I/O 错误 [英] RestTemplate ClientHttpResponse.getBody() throws I/O Error

查看:169
本文介绍了RestTemplate ClientHttpResponse.getBody() 抛出 I/O 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Spring RestTemplate 进行 RESTful 调用.我还使用自定义 ClientHttpRequestInterceptor 来记录请求和响应以进行调试.

I'm using Spring RestTemplate to make RESTful calls. I'm also using a custom ClientHttpRequestInterceptor to log the request and response for debugging purposes.

为了多次读取响应(一次用于日志记录,一次用于处理),我使用了 BufferingClientHttpRequestFactory.设置如下:

In order to read the response multiple times (once for the logging, once for processing) I use a BufferingClientHttpRequestFactory. Here's the setup:

ClientHttpRequestInterceptor ri = new LoggingRequestInterceptor();
List<ClientHttpRequestInterceptor> ris = new ArrayList<ClientHttpRequestInterceptor>();
ris.add(ri);
restTemplate.setInterceptors(ris);
restTemplate.setRequestFactory(new InterceptingClientHttpRequestFactory(
        new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()) , ris));

我现在正在针对返回 422 响应的请求测试此系统,但遇到了问题.从我的自定义 ClientHttpRequestInterceptor 的拦截方法中:

I'm testing this system right now against a request that returns a 422 response and am having problems. From within the intercept method of my custom ClientHttpRequestInterceptor:

ClientHttpResponse response = execution.execute(request, body);
if(response.getBody() != null) {
    logger.trace(IOUtils.toString(response.getBody(), "UTF-8"));
}

response.getBody() 抛出异常:

The response.getBody() throws an exception:

org.springframework.web.client.ResourceAccessException:I/O 错误:服务器返回 HTTP 响应代码:URL 为 422:https://testurl.com/admin/orders/564/fulfill.json;嵌套异常是 java.io.IOException:服务器返回 HTTP 响应代码:422 用于 URL:https://testurl.com/admin/orders/564/fulfill.json在org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:461)~[spring-web-3.1.2.RELEASE.jar:3.1.2.RELEASE] 在org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409)~[spring-web-3.1.2.RELEASE.jar:3.1.2.RELEASE]

org.springframework.web.client.ResourceAccessException: I/O error: Server returned HTTP response code: 422 for URL: https://testurl.com/admin/orders/564/fulfill.json; nested exception is java.io.IOException: Server returned HTTP response code: 422 for URL: https://testurl.com/admin/orders/564/fulfill.json at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:461) ~[spring-web-3.1.2.RELEASE.jar:3.1.2.RELEASE] at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409) ~[spring-web-3.1.2.RELEASE.jar:3.1.2.RELEASE]

不知道为什么会发生这种情况,但我打开了调试器并为 request.getBody() 设置了一个监视表达式.在该上下文中调用 request.getBody() 在它到达我的实际代码之前修复错误.

Not sure why this happens, but I turned on the debugger and I set up a watch expression for request.getBody(). The call to request.getBody() being made in that context before it gets to my actual code fixes the error.

推荐答案

sun.net.www.protocol.http.HttpURLConnection 抛出的 IOException 其中 RestTemplate 默认使用.查看 grepcode 中的源代码,如果 HTTP 状态代码为 4xx,getInputStream() 会抛出 IOException(对于 404 或 410,它会抛出更具体的 FileNotFoundException)

The IOException thrown from sun.net.www.protocol.http.HttpURLConnection which RestTemplate uses by default. Looking the source in grepcode, getInputStream() throws IOException if the HTTP status code is 4xx (for 404 or 410 it throws a more specific FileNotFoundException)

要解决这个问题,您需要通过 ClientHttpRequestFactory 提供不同的 HttpURLConnection 实现,该实现用作 RestTemplate 的构造函数参数,或使用 requestFactory 属性注入其中.例如

To get around this, you need to supply a different HttpURLConnection implementation via the ClientHttpRequestFactory that is used as a constructor parameter to RestTemplate, or injected into it with the requestFactory property. For example

 HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
 RestTemplate restTemplate = new RestTemplate(factory);

通过 Spring 注入执行此操作是留给读者的练习:-)

Doing this via Spring injection is an exercise left for the reader :-)

这篇关于RestTemplate ClientHttpResponse.getBody() 抛出 I/O 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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