【问题标题】:RestTemplate ClientHttpResponse.getBody() throws I/O ErrorRestTemplate ClientHttpResponse.getBody() 抛出 I/O 错误
【发布时间】:2015-08-02 02:28:32
【问题描述】:

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

为了多次读取响应(一次用于记录,一次用于处理),我使用了 BufferingClientHttpRequestFactory。这是设置:

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 的拦截方法中:

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

response.getBody() 抛出异常:

org.springframework.web.client.ResourceAccessException: I/O 错误: 服务器返回 HTTP 响应代码:422 用于 URL: 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]

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

【问题讨论】:

  • resttemplate 的 xml 配置在哪里
  • 这里也一样。另一个有趣的行为:在response.getBody() 之前调用response.getStatusCode() 也可以“解决”问题。

标签: java spring resttemplate


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 2019-01-21
    • 2017-09-08
    • 2014-10-26
    • 2014-04-05
    • 2015-09-15
    • 1970-01-01
    相关资源
    最近更新 更多