SpringBoot基礎教程2-1-3 異常處理規範

1. 概述

異常處理,在平時業務處理中不可避免;可是,閱讀代碼最頭疼的就是看到一堆try-catch語句,業務邏輯參雜其中,極難維護;那要怎樣優雅的處理異常呢?請耐心閱讀全文。java

2. 不負責任的處理異常

直接拋出異常或遺漏未捕獲異常,會怎樣?Spring Boot提供了一個默認的映射:/error,當處理中拋出異常以後,會轉到該請求中處理,而且該請求有一個全局的錯誤頁面用來展現異常內容git

@RestController
public class BadExceptionController {

    @GetMapping("/bad")
    public String bad(){
        // todo 業務邏輯

        Object object = null;
        // 模擬空指針異常
        object.toString();

        return "success";
    }
}

上述代碼極不負責,看看測試結果github

當調用者看到這個結果,估計一臉懵app

3. 醜陋的異常處理

常見的異常處理,在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;
    }
}

4. 優雅的異常處理

建立自定義業務異常類測試

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;
    }
}

這裏推薦一款神級插件lombokpom.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);
        }
    }
}

測試結果以下

5. 工程目錄

6. 結束語

說點什麼呢,有任何建議,歡迎留言探討,本文源碼


歡迎關注博主公衆號:Java十分鐘

歡迎關注博主公衆號

相關文章
相關標籤/搜索