我正在使用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)执行此操作是留给读者的练习:-)