我正在使用Spring's RestTemplate
对第三方服务进行一些API调用。
当响应以200 SUCCESS
的形式返回时,一切都会按预期进行。
但是,当响应为400-level error
时,我会从IOException
代码的最深处得到RestTemplate
。
这令人沮丧,因为我实际上已经编写了自己的ResponseErrorHandler
实现,该实现可以检查某些非200错误并执行我选择的操作(记录,重新格式化等)
在所有其他第三方API上,我的ResponseErrorHandler
的实现都有效,但是特别是对于此服务器,所有非200错误都导致此IOException
,并且从未实现我的自定义实现。 / p>
注意:当我尝试点击此命令时,Curl似乎通常会返回错误 第三方端点。
这是 Spring 错误吗?我在做蠢事吗?有关解决方法的想法?
相关代码
堆栈异常跟踪:
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://third-party.com/api/v2/some-resource": Server returned HTTP response code: 400 for URL: https://third-party.com/api/v2/some-resource; nested exception is java.io.IOException: Server returned HTTP response code: 400 for URL: https://third-party.com/api/v2/some-resource
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:743) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:669) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:607) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.myowncode.commons.client.RestClient.send(RestClient.java:74) ~[classes/:na]
我的自定义ResponseErrorHandler的用法
this.restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
restTemplate.setErrorHandler(new LoggingResponseErrorHandler());
我的自定义ResponseErrorHandler的示例
(这应该是无关紧要的,因为无论我是否已注册,以上都会发生)
public class LoggingResponseErrorHandler implements ResponseErrorHandler {
private static final Logger logger = LoggerFactory.getLogger(LoggingResponseErrorHandler.class);
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
// do my own thing
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
// do my own thing
}
}
答案 0 :(得分:0)
我怀疑这与BufferingClientHttpRequestFactory的使用有关。一个SimpleBufferingClientHttpRequest似乎可以让IOException转义其executeInternal()方法,而非缓冲版本SimpleStreamingClientHttpRequest可以捕获并忽略它,这大概会让您处理响应。
@Override
protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException {
try {
if (this.body != null) {
this.body.close();
}
else {
SimpleBufferingClientHttpRequest.addHeaders(this.connection, headers);
this.connection.connect();
// Immediately trigger the request in a no-output scenario as well
this.connection.getResponseCode();
}
}
catch (IOException ex) {
// ignore
}
return new SimpleClientHttpResponse(this.connection);
}
尝试像这样创建restTemplate:
this.restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory());