背景分析
在項目的開發中,無論是對底層的數據邏輯操做過程,仍是業務邏輯的處理過程,仍是控制邏輯的處理
過程,都不可避免會遇到各類可預知的、不可預知的異常。處理好異常對系統有很好的保護做用,同時
會大大提升用戶的體驗。設計
異常處理分析
Java項目中處理異常方式無非兩種,要麼執行trycatch操做,要麼執行throw操做(拋給其它對象處理),
不管採用哪一種方式,其目的是讓咱們的系統對異常要有反饋。但如今的問題是咱們如何讓這種反饋代碼
的編寫即簡單又直觀、友好。日誌
Java項目異常處理規範
咱們在處理異常的過程當中一般要遵循必定的設計規範,例如:code
第一:捕獲異常時與拋出的異常必須徹底匹配,或者捕獲異常是拋出異常的父類類型。
第二:避免直接拋出RuntimeException,更不容許拋出Exception或者Throwable,應使用有業務含義的自
定義異常(例如ServiceException)。
第三:捕獲異常後必須進行處理(例如記錄日誌)。若是不想處理它,須要將異常拋給它的調用者。
第四:最外層的邏輯必須處理異常,將其轉化成用戶能夠理解的內容。
第五:避免出現重複的代碼(Don’t Repeat Yourself),即DAY原則。對象
SpringBoot 工程下的異常處理實踐
第一種方式:直接在Controller方法中進行try操做開發
try{ ..... }catch(Exception e){ ..... }
假如controller中每一個方法都要這樣作,代碼量大而且可重用性太差,難以維護.get
第二種方式:在Controller中定義一個或多個異常處理方法,關鍵代碼以下:io
@ExceptionHandler(RuntimeException.class) @ResponseBody public String doHandleException(RuntimeException e){ log.error("exception {}",e.getMessage()); return e.getMessage(); }
全部的異常處理方法須要使用@ExceptionHandler進行描述進行描述,並聲明它描述的方法能夠處理的異常類型,
可是對於此
種方式而言,它只能處理當前Controller中各個方法出現的RuntimeException或者是其子類類型的異常,假如多個Controller類中須要一樣方式的異常處理方法,那直接在Controller類中定義異常處理方法並不
是一種很好的選擇.class
第三種方式:在控制邏輯層定義全局異常處理類以及異常處理方法,關鍵代碼以下:exception
@Slf4j //@ResponseBody //@ControllerAdvice @RestControllerAdvice public class GlobalExceptionHandler { 異常處理方法 @ExceptionHandler(IllegalArgumentException.class) public String doHandleException(IllegalArgumentException e){ log.error("IllegalArgumentException.exception {}",e.getMessage()); return e.getMessage(); } 異常處理方法 @ExceptionHandler(RuntimeException.class) public String doHandleException(RuntimeException e){ log.error("RuntimeException.exception {}",e.getMessage()); return e.getMessage(); }
其中,@RestControllerAdvice 註解描述的類爲全局異常處理類,當控制層方法中的異常沒有本身捕獲,
也沒有定義其內部的異常處理方法,底層默認會查找全局異常處理類,調用對應的異常處理方法進行異
常處理。方法