一、为什么要使用全局异常处理器?
什么是全局异常处理器?
就是把错误异常统一处理的方法。
应用场景:
1、当你使用jsr303参数校验器,如果参数校验不通过会抛异常,而且无法使用try-catch语句直接捕获,这时可以使用全局异常处理器来捕捉该异常。
2、当你自定义了一个异常类,可以在全局异常处理器中来捕捉该异常。(当然也可以直接在抛出异常处直接捕获,但是这样需要在每一个抛出的地方都写一次捕获代码,看起来不够美观且复用性不强,其他异常同理)。
所有异常都可以在全局异常处理器中捕获进行统一处理
二、具体使用步骤
1、定义统一的请求返回类型
public class Result<T> { private int code; private String msg; private T data; /** * 请求成功时调用 * @param data * @return */ public static <T> Result<T> success(T data){ return new Result<T>(data); } public static <T> Result<T> error(CodeMsg cm){ return new Result<T>(cm); } /** * 只传入数据默认成功,所以添加默认的code和msg * @param data */ private Result(T data) { this.code=0; this.msg="success"; this.data=data; } private Result(CodeMsg cm) { if(cm==null){ return; } this.code=cm.getCode(); this.msg=cm.getMsg(); } public int getCode() { return code; } public String getMsg() { return msg; } public T getData() { return data; } }
public class CodeMsg { private int code; private String msg; //通用的错误码 public static CodeMsg SUCCESS = new CodeMsg(0, "success"); public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务端异常"); public static CodeMsg BIND_ERROR = new CodeMsg(500101, "参数校验异常:%s"); //登录模块 5002XX public static CodeMsg SESSION_ERROR = new CodeMsg(500210, "Session不存在或者已经失效"); public static CodeMsg PASSWORD_EMPTY = new CodeMsg(500211, "登录密码不能为空"); public static CodeMsg STUDENTID_EMPTY = new CodeMsg(500212, "学号不能为空"); public static CodeMsg STUDENTID_ERROR = new CodeMsg(500213, "学号格式错误"); public static CodeMsg STUDENTIDE_NOT_EXIST = new CodeMsg(500214, "学号不存在"); public static CodeMsg PASSWORD_ERROR = new CodeMsg(500215, "密码错误"); public int getCode() { return code; } public String getMsg() { return msg; } public CodeMsg fillArgs(Object... args) { int code = this.code; String message = String.format(this.msg, args); return new CodeMsg(code, message); } private CodeMsg(int code,String msg) { this.code = code; this.msg = msg; } }
2、定义自己的异常类
public class GlobalException extends RuntimeException{ private static final long serialVersionUID = 1L; private CodeMsg cm; public GlobalException(CodeMsg cm) { super(cm.toString()); this.cm = cm; } public CodeMsg getCm() { return cm; } }
3、定义全局异常处理器
@ControllerAdvice //该注解定义全局异常处理类 //@ControllerAdvice(basePackages ="com.example.demo.controller") 可指定包 @ResponseBody public class GlobalExceptionHandler { @ExceptionHandler(value=Exception.class) //该注解声明异常处理方法 public Result<String> exceptionHandler(HttpServletRequest request, Exception e){ e.printStackTrace(); //对于自定义异常的处理 if(e instanceof GlobalException) { GlobalException ex = (GlobalException)e; return Result.error(ex.getCm()); //对于绑定异常的处理,使用jsr303中的自定义注解抛出的异常属于绑定异常 }else if(e instanceof BindException) { BindException ex = (BindException)e; List<ObjectError> errors = ex.getAllErrors(); ObjectError error = errors.get(0); String msg = error.getDefaultMessage(); return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg)); }else { return Result.error(CodeMsg.SERVER_ERROR); } } }
4、使用自己的定义的异常类
if(user == null) { throw new GlobalException(CodeMsg.STUDENTIDE_NOT_EXIST); }
看到的更容易理解一篇文章:https://www.cnblogs.com/zs-notes/p/9366066.html