- 與上篇日誌系統相輔相成的就是異常了,這邊博客主要講述如何配置全局異常/自定義異常。
相關注解
-
ControllerAdvice
:用來實現全局異常,需要定義類,添加該註解即可。處理的是Controller
層異常。示例代碼:
@ControllerAdvice public class ErrorController { }
因爲異常處理時候很多使用
JSON
來進行處理,所以很多時候ControllerAdvice
替換爲RestControllerAdvice
-
ExceptionHandler
:指定異常的處理方式,聲明於方法的上部。實例代碼:
//value可設定處理指定異常的類型, Exception爲處理所有 @ExceptionHandler(value = Exception.class) Object handleException(Exception e, HttpServletRequest request){ return object; }
代碼演示
-
Controller
部分@RestController @RequestMapping("user") public class UserController { @RequestMapping("error") public void error(){ int i = 1/0; } @RequestMapping("nullException") public void nullException(){ String str = null; str.indexOf(","); } }
-
異常處理類
@RestControllerAdvice public class ErrorController { //發生異常,寫入日誌,方便後期查看。 private static final Logger LOG = LoggerFactory.getLogger(ErrorController.class); /** * 默認處理所有異常 */ @ExceptionHandler(value = Exception.class) Object handleException(Exception e, HttpServletRequest request){ //此處是我的日誌格式。不影響代碼正常執行。 LOG.error("url{},msg{}",request.getRequestURI(),e.getMessage()); //定義map,返回異常信息方便操作 Map<String,Object> map = new HashMap<>(); //code參數,我理解爲狀態碼,這裏自由定義。 //如果不想使用map,使用實體類等都是可行的。 map.put("code",100); //msg,可自由定義。比如map.put("msg","請求參數錯誤!"); map.put("msg",e.getMessage()); return map; } }
-
示例
可以看到頁面輸出了倆種異常,存儲在map
的信息,不過並不直觀,且無法準確描述具體的異常。
異常拆分
-
一個方法處理所有的異常,是不妥的。建議拆分多個方法,每個方法對應特定異常,回顯特定信息,方便後期的問題定位。當然,下方這種代碼,理論上可以區分,但方法太長,不夠精簡。(想象一個方法一個類的情況)
@ExceptionHandler(value = Exception.class) Object handleException(Exception e, HttpServletRequest request){ Map<String,Object> map = new HashMap<>(); if (e instanceof ArithmeticException) { map.put("code",100); map.put("msg","請求參數錯誤"); } else if (e instanceof NullPointerException) { map.put("code",101); map.put("msg","空指針異常!"); } return map; }
-
個人建議下方這種
//默認爲所有異常,但優先級低於下方方法,因此有NullPointerException異常,執行下方方法,返回信息 @ExceptionHandler(value = Exception.class) Object handleException(Exception e, HttpServletRequest request){ //此處是我的日誌格式。不影響代碼正常執行 LOG.error("url{},msg{}",request.getRequestURI(),e.getMessage()); //定義map,返回異常信息方便操作 Map<String,Object> map = new HashMap<>(); map.put("code",100); map.put("msg","後臺發生錯誤"); return map; } //處理空指針異常 @ExceptionHandler(value = NullPointerException.class) Object handleNullPointerException(Exception e, HttpServletRequest request){ LOG.error("url{},msg{}",request.getRequestURI(),e.getMessage()); Map<String,Object> map = new HashMap<>(); map.put("code",100); //map.put("msg",e.getMessage()); map.put("msg","空指針異常"); return map; }
後期完善
- 關於異常再完善下,自定義錯誤頁面相關知識。
- 異常依賴於
Spring
的AOP
相關部分,出一篇AOP
的博客。