参考:https://blog.csdn.net/u011974797/article/details/82424004
https://www.cnblogs.com/liumz0323/p/10633785.html
问题描述:后台用Resttemplate请求失败的话只会在后台报错400,不会返回json错误原因
解决方法:使用HttpClientErrorException异常捕捉
try {
// resttemplate call api
} catch (HttpClientErrorException e) {
//捕捉HTTP异常
e.getResponseBodyAsString();
} catch (Exception e) {
//捕捉所有异常
e.printStackTrace();
}
描述:使用RestTemplate请求url,由于Token等验证信息参数失效,报出 401 HttpClientErrorException异常。
并且获取不到body消息体的错误信息。然而postman工具,是可以返回错误信息的。
原因:RestTemplate 有自己的默认错误处理。在默认的处理里,判断接收到401状态码则抛出
HttpClientErrorException异常,并执行了response.getBody(),这就导致我们后续获取不到body消息体了。
全局异常处理
@ControllerAdvice
public class ExceptionHandlerController { @ExceptionHandler(HttpClientErrorException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void HttpClientErrorExceptionHandler(HttpClientErrorException ex, HttpServletResponse res) {
UtilFunctions.log.error("HttpClientErrorExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
UtilFunctions.reportError("HttpClientErrorExceptionHandler: " + ex.toString(), ex, null);
JSONObject response = new JSONObject();
response.put("message", ex.getResponseBodyAsString());
res.setContentType("application/json;charset=utf-8");
try {
res.getWriter().append(response.toString());
} catch (IOException e) {
UtilFunctions.log.error("IOException, exception: {}", e.getMessage(), e);
}
}
}
/*
* 因为Content-Type=application/x-www-form-urlencoded, 所以post请求body中的参数格式也是 a=xxx&b=xxx;
* params可以为null
*
*/
private static HttpEntity<String> requestEntityRequireAuth(HttpServletRequest request, String params) {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Authorization", getAuthorization(request));
requestHeaders.add("accept", "*/*");
requestHeaders.add("connection", "Keep-Alive");
requestHeaders.add("Content-Type", "application/x-www-form-urlencoded");
requestHeaders.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0");
HttpEntity<String> requestEntity = new HttpEntity<String>(params, requestHeaders);
return requestEntity;
} private static HttpEntity<String> requestEntityNotRequireAuth(HttpServletRequest request, String params) {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("accept", "*/*");
requestHeaders.add("connection", "Keep-Alive");
requestHeaders.add("Content-Type", "application/x-www-form-urlencoded");
requestHeaders.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0");
HttpEntity<String> requestEntity = new HttpEntity<String>(params, requestHeaders);
return requestEntity;
} private static JSONObject returnResult(ResponseEntity<Object> result, HttpServletResponse response) {
int status = result.getStatusCodeValue();
JSONObject obj = new JSONObject();
if (status == 200) {
obj.put("data", result.getBody());
} else {
response.setStatus(status);
obj.put("message", result.getBody());
} return obj;
} private static JSONObject exceptionReturnResult(HttpClientErrorException e, HttpServletResponse response) {
int statusCode = e.getStatusCode().value();
JSONObject obj = new JSONObject();
response.setStatus(statusCode);
obj.put("message", e.getResponseBodyAsString());
return obj;
} /**
* GET请求,需要认证,返回结果中data为JSONObject
*/
public static Object getForObjectRequireAuth(HttpServletRequest request, HttpServletResponse response, String uri) throws Exception {
// 通过ContextProvider从spring容器获取RestTemplate实例
RestTemplate restTemplate = ContextProvider.getBean(RestTemplate.class);
ResponseEntity<Object> result = null;
try {
result = restTemplate.exchange(Config.BASE_SITE + uri, HttpMethod.GET, requestEntityRequireAuth(request, null), Object.class);
} catch (HttpClientErrorException e) {
return exceptionReturnResult(e, response);
}
return returnResult(result, response);
}