以前用springboot的時候,只知道捕獲異常使用try{}catch,一個接口一個try{}catch,這也是大多數開發人員異常處理的經常使用方式,雖然屢試不爽,但會形成一個問題,就是一個Controller下面,滿屏幕的try{}catch,看着一點都不優雅,一點都不符合小明的氣質,憋了這麼久,小明今天終於決定對全部異常實施統一處理的方案。java
開發準備
JDK八、正常的springboot項目程序員
代碼編寫
通用異常處理
其實Spring系列的項目全局異常處理方式早已存在,只不過咱們一直忙於搬磚,不多停下腳步去審視這個日夜與咱們相伴的朋友。爲了貼合主題,本次主要針對SpringBoot全局異常處理進行舉例說明。spring
SpringBoot中有一個@ControllerAdvice
的註解,使用該註解即表示開啓全局異常捕獲,接下來咱們只需在自定義的方法上使用@ExceptionHandler
註解,並定義捕獲異常的類型,對這種類型的異常進行統一的處理。springboot
舉個例子:app
假如咱們須要針對NullException(空指針異常,是Java程序員最痛恨的異常,沒有之一)進行全局處理(以下所示)。ide
@RestControllerAdvice public class GlobalExceptionHandler { /** * 處理空指針的異常 * @param req * @param e * @return */ @ExceptionHandler(value =NullPointerException.class) public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){ log.error("發生空指針異常!緣由是:",e); return ResponseUtil.error(ResponseCode.ERROR); } }
訥,就這麼簡單。其餘可能發生的異常,均可以以這種方式處理快速處理。此處你們應該表現的十分興奮,但請不要高興太早,由於接下來,有更令激動人心的事情。工具
自定義異常處理
自定義一個異常
import lombok.AllArgsConstructor; import lombok.Data; import lombok.experimental.Accessors; /** * @Description 自定義異常 * @Date 2019-08-05 15:49 * @Created by 程序員小明 */ @Data @AllArgsConstructor @Accessors(chain = true) public class BizException extends RuntimeException { /** * 錯誤碼 */ protected Integer errorCode; /** * 錯誤信息 */ protected String errorMsg; }
顯而易見,這個異常繼承了RuntimeException
,屬於運行時異常。細心的朋友已經發現,我使用了Lombok插件,很是契合今天的主題,給你們簡單介紹一下:idea
lombok是一個能夠幫助咱們簡化java代碼編寫的工具類,尤爲是簡化javabean的編寫,即經過採用註解的方式,消除代碼中的構造方法,getter/setter等代碼,使咱們寫的類更加簡潔(若是使用的IDE是idea,須要安裝插件哈)。插件
定義過以後,咱們就能夠和以前處理NullException方式同樣處理咱們自定義的異常。包括處理其餘異常,都是這種方式。直接貼代碼。指針
@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { /** * 處理自定義的業務異常 * @param req * @param e * @return */ @ExceptionHandler(value = BizException.class) public BaseResponseFacade bizExceptionHandler(HttpServletRequest req, BizException e){ log.error("發生業務異常!緣由是:{}",e.getErrorMsg()); return ResponseUtil.error(e.getErrorCode(),e.getErrorMsg()); } /** * 處理空指針的異常 * @param req * @param e * @return */ @ExceptionHandler(value =NullPointerException.class) public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){ log.error("發生空指針異常!緣由是:",e); return ResponseUtil.error(ResponseCode.ERROR); } /** * 處理其餘異常 * @param req * @param e * @return */ @ExceptionHandler(value =Exception.class) public BaseResponseFacade exceptionHandler(HttpServletRequest req, Exception e){ log.error("未知異常!緣由是:",e); return ResponseUtil.error(ResponseCode.INTERNAL_SERVER_ERROR); } }
整個全局異常處理方式核心就是以上介紹這些。下面用一個Demo給你們舉個例子
@GetMapping("/test") public BaseResponseFacade test(){ if(true){ throw new BizException(1,"error"); } return ResponseUtil.success(); }
地址欄請求,進入這個方法後,會拋出異常,此時全局異常生效,就會返回異常處理事後的信息
{"errorCode":1,"errorMsg":"error","data":null}
到此整個流程都然跑通了。固然,好多地方均可以根據咱們自身實際業務狀況以此爲基礎進一步豐富,好比返回數據能夠改爲跳轉某一個具體的頁面。這樣的出場方式是否是都很優雅?你們有什麼問題,期待各位留言。