背景:某接口需要Oath2认证,需要获取对应token信息,由于该接口请求使用 x-www-form-urlencoded 经过尝试,使用hutool的方法均不能满足上述需求,转而使用restTemplate来做http请求。但是又碰到了 在请求返回异常时直接抛出,而不是正常打印相关信息,因此需要做异常处理,代码逻辑如下。
String pelecnTokenEndpoint="xxx";
String ClientId = "xxx";
String ClientSecret = "xxx";
String scope = "xxx";
String token = null;
HttpHeaders headers = new HttpHeaders();
headers.set("Content-type","application/x-www-form-urlencoded");
MultiValueMap<String,Object> formMap = new LinkedMultiValueMap<>();
formMap.add("grant_type","client_credentials");
formMap.add("client_id",pelecnClientId);
formMap.add("client_secret",pelecnClientSecret);
formMap.add("scope",scope);
String content = JSONUtil.toJsonStr(formMap);
RestTemplate restTemplate = new RestTemplate();
//todo:关键配置
restTemplate.setErrorHandler(new RestTemplateErrorHandler());
HttpEntity<MultiValueMap> doneEntity = new HttpEntity<>(formMap,headers);
//String body = restTemplate.postForObject(pelecnTokenEndpoint, doneEntity, String.class);
ResponseEntity<PanasonicResponseTO> stringResponseEntity = restTemplate.postForEntity(pelecnTokenEndpoint, doneEntity, PanasonicResponseTO.class);
log.info("[接口]响应:[{}]",JSONObject.toJSONString(stringResponseEntity));
cn.hutool.json.JSONObject tokenResponse = JSONUtil.parseObj(stringResponseEntity);
if(!StringUtil.isEmpty(stringResponseEntity.getBody().getAccess_token())){
token = stringResponseEntity.getBody().getAccess_token();
log.info("access_token:{}",token);
}else {
log.info("token请求返回状态信息:{},statusCodeValue:{},消息体:{}",stringResponseEntity.getStatusCode(),stringResponseEntity.getStatusCodeValue(),stringResponseEntity.getBody().getError());
}
这里的关键点是restTemplate.setErrorHandler(new RestTemplateErrorHandler())
下面,看一下如果没有做处理前的情况:
这里直接抛出了异常,而不是将异常信息返回,需要看一下为什么会产生这个东西?
在做restTemplate.postForEntity() 这里有execute
这里会走到 doExecute
在走进doExecute时,会走进handleResponse
然后,处理响应,看handleError方法
这个handlerError实现了defaultResponseErrorHandler
最终,在返回时根据handleError处理
所以这里是直接捕获异常出来,而不是打印相关信息。
处理方法
如果想要自己捕获异常信息,自己处理异常可以通过实现ResponseErrorHandler类来实现,
public interface ResponseErrorHandler {
// 标示 Response 是否存在任何错误。实现类通常会检查 Response 的 HttpStatus。
boolean hasError(ClientHttpResponse var1) throws IOException;
// 处理 Response 中的错误, 当 HasError 返回 true 时才调用此方法。
void handleError(ClientHttpResponse var1) throws IOException;
// handleError 的替代方案,提供访问请求URL和HTTP方法的额外信息。
default void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
this.handleError(response);
}
}
如果想要按照自己想要的打印信息来返回,即类似HttpClient从Response中获取HttpStatus和body中的报错信息,而不是抛出异常,可以使用自己的Handler处理,可以使用以下实现
@Component
public class RestTemplateErrorHandler implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
return true;
}
@Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
}
}
这里hasError直接正常范湖,就可以不做异常抛出了。