resttemplate 设置400不抛异常
问题描述
最近在对接 gitlab相关的api的时候发现一个问题
gitlab 返回的错误信息伴随的错误码一般是 400 500 之类项目中
我用的http请求工具是 resttemplate
该工具在遇到400 500 之类的返回值的时候会直接抛出异常这样我就获取不到对应的返回信息了
解决方案
设置 resttemplate 遇到400 错误码 不报错
简单看下源码
废话不多说,直接开始
Resttemlate类中 闭眼一看 直接进入 handleResponse方法
protected void handleResponse(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
ResponseErrorHandler errorHandler = getErrorHandler();
// 判断 状态码是是不是 4 或者 5开头的
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) {
//如果有error 处理 error
errorHandler.handleError(url, method, response);
}
}
然后进入 handleError 方法 就在发方法中 抛出异常
protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
String statusText = response.getStatusText();
HttpHeaders headers = response.getHeaders();
byte[] body = getResponseBody(response);
Charset charset = getCharset(response);
//statusCode.series() 该方法提取错误码的第一位
switch (statusCode.series()) {
// 4开头
case CLIENT_ERROR:
throw HttpClientErrorException.create(statusCode, statusText, headers, body, charset);
// 5开头
case SERVER_ERROR:
throw HttpServerErrorException.create(statusCode, statusText, headers, body, charset);
default:
throw new UnknownHttpStatusCodeException(statusCode.value(), statusText, headers, body, charset);
}
}
状态码是 4 开头或者5开头的话 会直接抛出异常
解决办法
既然 已经 定位到具体代码 解决方法很简单,自己定义一个error处理器,set到restTemplate中就可以了
/**
* gitlab 专用的resttemplate 返回400状态码不再报错处理
* @param builder
* @return
*/
@Bean
public RestTemplate gitLabRestTemplate(RestTemplateBuilder builder) {
RestTemplate restTemplate = builder.build();
restTemplate.setRequestFactory(clientHttpRequestFactory());
//设置成自己的 errorhandle
restTemplate.setErrorHandler(new MyErrorHandler());
return restTemplate;
}
public class MyErrorHandler implements ResponseErrorHandler {
@Override
//判断error 直接返回false
public boolean hasError(ClientHttpResponse response) throws IOException {
return false;
}
@Override
//不再处理error 其实只要上面的就可以了
public void handleError(ClientHttpResponse response) throws IOException {
}
}
因为我往容器里面注入了两个 restTemplate 所有引用的时候只能通过@resource 通过名字来 引用
至此结束,小小的一个bug,多一些积累,多一些分享,多一些记忆。