RestTemplate 自定义超时时间及自定义错误处理

874 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

给大家分享一下RestTemplate如何设置超时时间及返回状态码的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

自定义错误处理

默认情况下使用RestTemplate如果返回结果的状态码是200的话就正常处理,否则都会抛出异常

如果我们想要拿到所有的返回,包括非200的,怎么做?

分析

通过调试,我们定位到错误处理在 hasError 这个方法

// 传入响应,返回是否有错误
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
        int rawStatusCode = response.getRawStatusCode();
        HttpStatus statusCode = HttpStatus.resolve(rawStatusCode);
        return (statusCode != null ? hasError(statusCode) : hasError(rawStatusCode));
}

往上一级,看什么地方调用了这个方法

protected void handleResponse(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
        ResponseErrorHandler errorHandler = getErrorHandler();
        boolean hasError = errorHandler.hasError(response);
        if (logger.isDebugEnabled()) {
                try {
                        int code = response.getRawStatusCode();
                        HttpStatus status = HttpStatus.resolve(code);
                        logger.debug("Response " + (status != null ? status : code));
                }
                catch (IOException ex) {
                        // ignore
                }
        }
        if (hasError) {
                errorHandler.handleError(url, method, response);
        }
}

首先 调用 boolean hasError = errorHandler.hasError(response);得到 hasError,然后通过

if (hasError) {
        errorHandler.handleError(url, method, response);
}

判断是否调用errorHandler处理。

通过分析,现在我们有两种方法

  1. 自己实现 handleResponse 方法 - 较为复杂
  2. 自己实现 errorHandler - 较为简单

实现自定义错误处理器

只需要将hasError方法的返回值更改为默认true就可以了,以后不管状态码是200还是其它的都会返回结果,handleError现在已经名存实亡,所以保留空方法就行。

@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
    RestTemplate restTemplate = new RestTemplate(factory);
    ResponseErrorHandler responseErrorHandler = new ResponseErrorHandler() {
        @Override
        public boolean hasError(ClientHttpResponse response) throws IOException {
            return true;
        }
        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
        }
    };
    restTemplate.setErrorHandler(responseErrorHandler);
    return restTemplate;
}

自定义超时时间

RestTemplate默认使用的是SimpleClientHttpRequestFactory工厂方法,默认值都是-1,也就是没有超时时间。

private int connectTimeout = -1;
private int readTimeout = -1;

底层是使用URLConnection,而URLConnection实际上是封装了Socket,Socket我们知道是没有超时时间限制的,所以我们必须设置超时时间,否则请求的URL一直卡死程序

@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    //读取超时5秒,默认无限限制,单位:毫秒
    factory.setReadTimeout(5000);
    //连接超时10秒,默认无限制,单位:毫秒
    factory.setConnectTimeout(10000);
    return factory;
}