参考: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); }