一、為什么要使用全局異常處理器?
什么是全局異常處理器?
就是把錯誤異常統一處理的方法。
應用場景:
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