Spring RestTemplate产生的IOException未被自定义ResponseErrorHandler

时间:2019-02-13 14:53:03

标签: java spring rest

我正在使用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
    }

}

1 个答案:

答案 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());