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