今天开发过程中遇到一个问题记录下:
问题
在使用RestTemplate进行方法请求的过程中本身想通过接口响应状态码(例如:HTTPStatus 401/500)进行不同的逻辑处理,代码写完之后测试发现如果接口响应状态不等于200的话,就直接抛异常了,且不能直接在Exception中获取到statusCode。
代码如下:
try {
ResponseEntity<UserInfoRespDTO> exchange = restTemplate.exchange(requestUrl, HttpMethod.GET, httpEntity, UserInfoRespDTO.class);
if (HttpStatus.OK.equals(exchange.getStatusCode())){
UserInfoRespDTO body = exchange.getBody();
log.info("IamApiServiceImpl.getUserInfo接口出参{}", JSON.toJSONString(body));
return body;
} else if (HttpStatus.UNAUTHORIZED.equals(exchange.getStatusCode())) {
/**
* 1.删除redis中缓存的token重新获取
* 2.token获取成功之后重新请求Oauth2接口
*/
} else {
/**
* return 异常
*/
}
}catch(Exception var){
var.printStackTrace();
log.error("访问ipass token获取用户信息接口异常{}", var.getMessage());
UserInfoRespDTO dto = new UserInfoRespDTO();
dto.setErrcode(HttpStatus.INTERNAL_SERVER_ERROR.toString());
dto.setMsg("调用Ipss API接口服务异常");
return dto;
}
ok开始排查问题,查看底层代码,直接查看restTemplate.exchage()源码
1. exchange()方法中调用了doExecute()方法,该方法中有一个handleResponse的处理方法
2.该方法中handleError()方法中进行了异常的处理
3.发现方法如果异常的话restTemplate直接throw new ****Exception了,定位到问题,根据异常的情况catch中直接捕获异常即可
解决方案
通过对源码的查看,发现如果使用restTemplate调用方法异常的话,底层抛出异常未HttpClientErrorException,直接在catch中捕获异常即可
try {
ResponseEntity<TokenRespDTO> exchange = restTemplate.exchange(requestUrl, HttpMethod.POST, httpEntity, TokenRespDTO.class);
body = exchange.getBody();
return body;
} catch (HttpClientErrorException var) {
if (HttpStatus.UNAUTHORIZED.equals(var.getStatusCode())) {
//接口响应401 处理响应业务逻辑
} else {
//接口异常 例如500等异常,在else里面处理
}
} catch (Exception e) {
//此处抛出Exception 是为了避免出现一些接口调用外的一些异常
}