在日常开发中经常会用到RestTemplate这一客户端进行访问其他的接口时,经常会遇到异常处理的问题,关于RestTemplate的异常处理,主要会用到一个接口org.springframework.web.client.ResponseErrorHandler
,源码如下:
public interface ResponseErrorHandler {
// 判断是否有异常
boolean hasError(ClientHttpResponse response) throws IOException;
// 如果有问题,进入这个方法,处理问题
void handleError(ClientHttpResponse response) throws IOException;
}
ResponseErrorHandler 会根据RestTemplate
的响应码来判断返回结果是否有异常。
接下来看一下该接口的实现类DefaultResponseErrorHandler
,如下:
// 根据http code判断是否有问题
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
return (statusCode != null && hasError(statusCode));
}
// 如果返回的http code是标准的4xx, 5xx,那么就认为有问题了
protected boolean hasError(HttpStatus statusCode) {
return (statusCode.series() == HttpStatus.Series.CLIENT_ERROR ||
statusCode.series() == HttpStatus.Series.SERVER_ERROR);
}
// 接下来是异常的处理
@Override
public void handleError(ClientHttpResponse response) throws IOException {
HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
if (statusCode == null) {
byte[] body = getResponseBody(response);
String message = getErrorMessage(response.getRawStatusCode(),
response.getStatusText(), body, getCharset(response));
throw new UnknownHttpStatusCodeException(message,
response.getRawStatusCode(), response.getStatusText(),
response.getHeaders(), body, getCharset(response));
}
handleError(response, statusCode);
}
protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
switch (statusCode.series()) {
case CLIENT_ERROR:
throw new HttpClientErrorException(statusCode, response.getStatusText(),
response.getHeaders(), getResponseBody(response), getCharset(response));
case SERVER_ERROR:
throw new HttpServerErrorException(statusCode, response.getStatusText(),
response.getHeaders(), getResponseBody(response), getCharset(response));
default:
throw new UnknownHttpStatusCodeException(statusCode.value(), response.getStatusText(),
response.getHeaders(), getResponseBody(response), getCharset(response));
}
}
接下来说明一下如何使用该接口类,这里主要有三种方式:
方式一:给RestTemplate
对象设置该属性
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
@Override
protected boolean hasError(HttpStatus statusCode) {
return super.hasError(statusCode);
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
super.handleError(response);
}
});
方式二:自定义一个类来实现ResponseErrorHandler
接口
public class Test implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return false;
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
}
方式三:直接使用try..catch
来处理
RestTemplate restTemplate = new RestTemplate();
try{
HttpEntity<String> ans=restTemplate.exchange(.......);
} catch (HttpClientErrorException e) {
throw new xxxxException(HttpStatus.UNAUTHORIZED,JSON.parseObject(e.getResponseBodyAsString()).get("message").toString());
} catch (HttpServerErrorException e) {
throw new xxxxException(HttpStatus.INTERNAL_SERVER_ERROR,JSON.parseObject(e.getResponseBodyAsString()).get("message").toString());
} catch (UnknownHttpStatusCodeException e) {
throw new xxxxException(HttpStatus.INTERNAL_SERVER_ERROR,JSON.parseObject(e.getResponseBodyAsString()).get("message").toString());
}
// xxxxException代指自定义类型异常