springmvc请求参数异常统一处理,结合钉钉报告信息定位bug位置
Posted xy-ouyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springmvc请求参数异常统一处理,结合钉钉报告信息定位bug位置相关的知识,希望对你有一定的参考价值。
参考之前一篇博客:springmvc请求参数异常统一处理
1、ExceptionHandlerController
package com.oy.controller; import java.text.MessageFormat; import java.util.ResourceBundle; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.TypeMismatchException; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; import com.alibaba.fastjson.JSONObject; import com.oy.exception.ForbiddenException; import com.oy.exception.JwebException; import com.oy.utils.ErrCode; import com.oy.utils.Response; import com.oy.utils.UtilFunctions; @ControllerAdvice public class ExceptionHandlerController { @ExceptionHandler(RuntimeException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public JSONObject runtimeExceptionHandler(RuntimeException ex) { UtilFunctions.log.error("runtimeExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); UtilFunctions.reportError("runtimeExceptionHandler: " + ex.toString(), ex); JSONObject response = new JSONObject(); response.put("message", "Internal Server Error"); return response; } @ExceptionHandler(NullPointerException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public JSONObject nullPointerExceptionHandler(NullPointerException ex) { UtilFunctions.log.error("nullPointerExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); UtilFunctions.reportError("runtimeExceptionHandler: " + ex.toString(), ex); JSONObject response = new JSONObject(); response.put("message", "Internal Server Error"); return response; } /*----- REQUEST ERROR -----*/ @ExceptionHandler({ ForbiddenException.class }) @ResponseStatus(HttpStatus.FORBIDDEN) @ResponseBody public JSONObject requestForbidden(ForbiddenException ex) { UtilFunctions.log.error("ForbiddenExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); JSONObject response = new JSONObject(); response.put("message", ex.getMessage()); return response; } @ExceptionHandler({ TypeMismatchException.class }) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public JSONObject requestTypeMismatch(TypeMismatchException ex) { UtilFunctions.log.error("TypeMismatchExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); JSONObject response = new JSONObject(); // response.put("message", "Bad Request"); // response.put("message", "Bad Request, parameter type of " + ex.getPropertyName() + " need be " + ex.getRequiredType()); if (Double.class.equals(ex.getRequiredType()) || Integer.class.equals(ex.getRequiredType())) { response.put("message", "Bad Request, " + ex.getValue() + " not a number"); } else { String strTemplate = "Bad Request, {0} is invalid, a type of {1} is needed"; response.put("message", MessageFormat.format(strTemplate, ex.getValue(), ex.getRequiredType().getName())); } return response; } @ExceptionHandler({ MissingServletRequestParameterException.class }) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public JSONObject requestMissingServletRequest(MissingServletRequestParameterException ex) { UtilFunctions.log.error("MissingServletRequestParameterExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); JSONObject response = new JSONObject(); // response.put("message", "Bad Request"); String strTemplate = "Bad Request, param:{0} is required, type:{1}"; response.put("message", MessageFormat.format(strTemplate, ex.getParameterName(), ex.getParameterType())); return response; } @ExceptionHandler({ NoSuchRequestHandlingMethodException.class }) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public JSONObject NoSuchRequestHandlingMethodExceptionHandler(NoSuchRequestHandlingMethodException ex) { UtilFunctions.log.error("NoSuchRequestHandlingMethodExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); JSONObject response = new JSONObject(); response.put("message", "Not Found"); return response; } /*----- REQUEST ERROR -----*/ @ExceptionHandler({ HttpMessageNotReadableException.class }) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public JSONObject requestNotReadable(HttpMessageNotReadableException ex) { UtilFunctions.log.error("HttpMessageNotReadableExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); JSONObject response = new JSONObject(); response.put("message", "Bad Request"); return response; } @ExceptionHandler({ HttpRequestMethodNotSupportedException.class }) @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) @ResponseBody public JSONObject request405(HttpRequestMethodNotSupportedException ex) { UtilFunctions.log.error("HttpRequestMethodNotSupportedExceptionHandler, msg: {}, exception: {}", ex.toString(), ex); JSONObject response = new JSONObject(); // response.put("message", "Method Not Allowed"); response.put("message", ex.getMessage()); return response; } @ExceptionHandler({ JwebException.class }) @ResponseStatus(HttpStatus.OK) @ResponseBody public JSONObject jwebExceptionHandler(JwebException ex, HttpServletRequest request) { UtilFunctions.log.error("jwebExceptionHandler, info: {}, exception: {}", ex.getMessage(), ex); UtilFunctions.reportError("jwebExceptionHandler, " + ex.toString(), null); //JSONObject response = new JSONObject(); //response.put("code", ErrCode.SER_INTERNAL_ERR); //response.put("message", ex.getMessage()); //response.put("message", "The system is busy. Please try again later."); ResourceBundle resourceBundle = (ResourceBundle) request.getAttribute("resourceBundle"); String message = UtilFunctions.getMessage(resourceBundle, "SYSTEM_BUSY"); return new Response(ErrCode.SER_INTERNAL_ERR, message).toJson(); } }
2、springmvc全局异常捕获,整合钉钉打印异常相关信息
UtilFunctions#reportError()方法:
public static void reportError(String msg, Exception err) { if (err != null) { log.error("msg:{}, err:{}", msg, err); } JSONObject content = new JSONObject(); //content.put("content", "hostname:" + Config.HOSTNAME + "\\n" + "errMsg:" + msg); content.put("content", "hostname:" + Config.HOSTNAME + "\\n" + "errMsg:" + msg + "\\n" + getStackTraceInfo(err)); JSONObject obj = new JSONObject(); obj.put("msgtype", "text"); obj.put("text", content.toString()); String query = obj.toString(); try { URL url = new URL("https://oapi.dingtalk.com/robot/send?access_token=" + Config.DINGTOKEN); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setUseCaches(false); connection.setInstanceFollowRedirects(true); connection.setRequestProperty("Content-Type", "application/json"); connection.connect(); try (OutputStream os = connection.getOutputStream()) { os.write(query.getBytes("UTF-8")); } try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { } connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } }
public static String printStackTraceToString(Throwable t) { // StringWriter sw = new StringWriter(); // t.printStackTrace(new PrintWriter(sw, true)); // return sw.getBuffer().toString(); StringWriter sw = null; PrintWriter pw = null; try { sw = new StringWriter(); pw = new PrintWriter(sw); t.printStackTrace(pw); pw.flush(); sw.flush(); return sw.getBuffer().toString(); } finally { if (sw != null) { try { sw.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (pw != null) { pw.close(); } } }
public static String getStackTraceInfo(Throwable t) { String stackTraceInfo = ""; String stackTrace = printStackTraceToString(t); String regex = "at amberai.jweb(\\\\S*)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(stackTrace); while (matcher.find()) { stackTraceInfo += matcher.group() + "\\n"; // UtilFunctions.log.info("=====matcher.group:{}" + matcher.group()); } return stackTraceInfo; }
3、测试
3.1、手动抛出JwebException
TradeOrder tradeOrder = tradeService.getOrderByHashId(hashId); if (tradeOrder == null) { String errMsg = MessageFormat.format("TradeController#getOrder error, tradeOrder:{0}, uid:{1}", tradeOrder, uid); throw new JwebException(errMsg); } UtilFunctions.log.info("grpc getOrder info, uid:{}, tradeOrder.getUserid:{}", tradeOrder, uid, tradeOrder.getUserid()); if (!uid.equals(tradeOrder.getUserid())) { String errMsg = MessageFormat.format("TradeController#getOrder error, uid:{0}, tradeOrder.getUserid:{0}", uid, tradeOrder.getUserid()); throw new JwebException(errMsg); }
3.2、代码出现RuntimeException,比如
int a = 1/0;
以上是关于springmvc请求参数异常统一处理,结合钉钉报告信息定位bug位置的主要内容,如果未能解决你的问题,请参考以下文章
javaweb异常提示信息统一处理(使用springmvc,附源码)
SpringMvc,Springboot统一校验自定义异常全局异常处理
SpringMvc,Springboot统一校验自定义异常全局异常处理