我正在使用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()引发异常:



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

最佳答案

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

为了解决这个问题,您需要通过HttpURLConnection提供另一个ClientHttpRequestFactory实现,该实现用作RestTemplate的构造函数参数,或通过requestFactory属性注入(inject)到其中。例如

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

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

10-06 16:00