異常處理,在平時業務處理中不可避免;可是,閱讀代碼最頭疼的就是看到一堆try-catch
語句,業務邏輯參雜其中,極難維護;那要怎樣優雅的處理異常呢?請耐心閱讀全文。java
直接拋出異常或遺漏未捕獲異常,會怎樣?Spring Boot提供了一個默認的映射:/error,當處理中拋出異常以後,會轉到該請求中處理,而且該請求有一個全局的錯誤頁面用來展現異常內容git
@RestController public class BadExceptionController { @GetMapping("/bad") public String bad(){ // todo 業務邏輯 Object object = null; // 模擬空指針異常 object.toString(); return "success"; } }
上述代碼極不負責,看看測試結果github
當調用者看到這個結果,估計一臉懵app
常見的異常處理,在
try-catch
塊中,手動封裝返回對應結果;該方法相比上面,雖然封裝了異常,可是異常處理邏輯,嵌在業務邏輯中,當要修改業務邏輯時,也不可避免的新增對於異常處理邏輯,耦合度很是高ide
@RestController public class UglyExceptionController { @GetMapping("/ugly") public Map<String, String> ugly(){ Map<String, String> result = new HashMap<>(); // TODO 直接捕獲全部代碼塊,而後在 cache try { int i = 10 / 0; result.put("code", "200"); result.put("data", "具體返回的結果集"); } catch (Exception e) { result.put("code", "500"); result.put("message", "請求錯誤"); } return result; } }
建立自定義業務異常類測試
public class BusinessException extends RuntimeException{ public BusinessException(String message) { super(message); } }
建立通用響應處理類this
@Data public class R<T> implements Serializable { private T data; //服務端數據 private int status = 0; //狀態碼,0:成功,1:失敗 private String msg = ""; //描述信息 public static R isOk() { return new R().msg("成功"); } public static R isFail() { return new R().status(1).msg("失敗"); } public static R isFail(Throwable e) { return isFail().msg(e); } public R msg(Throwable e) { this.setMsg(e.toString()); return this; } public R data(T data) { this.setData(data); return this; } public R msg(String msg){ this.setMsg(msg); return this; } public R status(int status) { this.setStatus(status); return this; } }
這裏推薦一款神級插件
lombok
,pom.xml
添加以下依賴,主要做用是使用註解
在編譯時生成基礎方法插件
<!--編譯時生效--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.20</version> <scope>provided</scope> </dependency>
建立統一異常處理類(重點)指針
// 若是要驗證BadException 和 UglyException請註釋@ControllerAdvice @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = BusinessException.class) public R businessExceptionHandler(BusinessException exception) { return R.isFail(exception); } @ExceptionHandler(value = Exception.class) public R exceptionHandler(Exception exception) { return R.isFail(exception); } }
@ControllerAdvice
捕獲 Controller
層拋出的異常,若是添加 @ResponseBody
返回信息則爲JSON
格式。@RestControllerAdvice
至關於 @ControllerAdvice
與 @ResponseBody
的結合體。@ExceptionHandler
統一處理一種類的異常,減小代碼重複率,下降複雜度。建立Controllercode
@RestController public class BusinessController { @GetMapping("/business/{param}") public R business(@PathVariable String param){ if("ok".equals(param)){ return R.isOk(); } else { throw new BusinessException("business exception: param = " + param); } } }
測試結果以下
說點什麼呢,有任何建議,歡迎留言探討,本文源碼。
歡迎關注博主公衆號:Java十分鐘