Spring RestTemplate没有将401映射到HttpClientErrorException

时间:2016-11-17 23:13:46

标签: java spring

运行Spring RestTemplate,我们遇到了意外行为,使用了相当典型的HttpClientErrorException; 401错误未转换为ResourceAccessException

具体来说,当我们从服务器收到预期的401时,我们会收到一个IOException包裹Server returned HTTP response code: 401 for URL: ...,其中包含sun.net.www.protocol.http.HttpURLConnection消息,该消息在{{1}的内部深处提升}}

我们的模板配置或多或少如此:

public RestTemplate restTemplate() {
    PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
    // connections per route is not a meaningful limit for us, so set very high
    poolingHttpClientConnectionManager.setDefaultMaxPerRoute(10000);
    poolingHttpClientConnectionManager.setMaxTotal(100);

    CloseableHttpClient client = HttpClientBuilder.create().setConnectionManager(poolingHttpClientConnectionManager).build();

    HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

    RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
    restTemplate.setInterceptors(interceptors);
    return restTemplate;
}

我们对客户端的使用如下:

protected <T, U> ResponseEntity<T> request(UserClientAccount account, U body, String url, HttpMethod httpMethod,
                                           ParameterizedTypeReference<T> responseType, boolean retry) {
    try {
        HttpEntity<U> request = createHttpEntity(body, account.getToken(this));
        return getRestTemplate().exchange(url, httpMethod, request, responseType, new HashMap<String, String>());
    }
    catch (HttpClientErrorException e) {
        if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {
                if (retry) {
                    log.warn("Unauthorized response for {}. Refreshing token to retry...", url);
                    refreshToken(account);
                    // tries again
                    return request(account, null, url, httpMethod, responseType, false);
                }
                else {
                    log.error("Unauthorized error calling {}. All attempts to retry exhausted ", url);
                    throw e; 
                }
        }
        throw new ProgramException("Error while performing " + httpMethod + " request to " + url + ". " +
                "Response body: " + e.getResponseBodyAsString(), e);
    }
}

我们对HttpClientErrorException的追捕从未被击中;相反,我们收到ResourceAccessException,原因是上述IOException

我们做错了什么?

0 个答案:

没有答案