1. 程式人生 > >springboot 異常處理-自定義異常及攔截異常

springboot 異常處理-自定義異常及攔截異常

一般解決異常的思路如下 

 

 

這裡我就主要講講自定義異常的攔截

 

為什麼要拋自定義異常?

1.service方法在執行過程出現異常在哪捕獲?在service中需要都加try/catch,如果在controller也需要新增
try/catch,程式碼冗餘嚴重且不易維護。

2.在統一異常處理類中去捕獲異常,無需controller捕獲異常,向用戶返回統一規範的響應資訊

3.將異常以json 資料格式返回,

 

2.自定義資訊響應介面 

1.建立一個異常響應介面,需要丟擲異常的時候寫個繼承類就行...

public interface ResultCode {
    //操作是否成功,true為成功,false操作失敗
    boolean success();
    //操作程式碼
    int code();
    //提示資訊
    String message();

}

 

3.自定義異常類

public class CustomException extends RuntimeException {

    private ResultCode  resultCode;

//    重寫構造
    public CustomException(ResultCode resultCode){
        //異常資訊為錯誤程式碼+異常資訊
        super("錯誤程式碼:"+resultCode.code()+"錯誤資訊:"+resultCode.message());
        this.resultCode = resultCode;
    }


//提供獲取異常資訊的方法
    public  ResultCode getResultCode() {
        return resultCode;
    }

}

 

建立一個丟擲異常的工具類

//丟擲異常的工具類
public class ExceptionCast {


    public static void cast(ResultCode resultCode){
        throw new CustomException(resultCode);
    }
}

 

4 . 建立異常捕獲類

@ControllerAdvice
public class ExceptionCatch {
    //日誌列印類
    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);

    //捕獲 CustomException異常
    @ExceptionHandler(CustomException.class)
    @ResponseBody   //響應json資料
    public ResponseResult customException(CustomException e){

//        列印日誌                                          e.getMessage() 列印自定義丟擲的異常資訊  也就是 這句 super("錯誤程式碼:"+resultCode.code()+"錯誤資訊:"+resultCode.message());
        LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);

        //獲取詳細的資訊  
        ResultCode resultCode = e.getResultCode();
        
        //建立響應類,也就是最終傳給頁面的資料   
        ResponseResult response = new ResponseResult(resultCode);
        
        return response;
    }


}

   //建立響應類,也就是最終傳給頁面的資料   
        ResponseResult response = new ResponseResult(resultCode); 其實就是對資料的封裝

 

   public ResponseResult(ResultCode resultCode){
        this.success = resultCode.success();
        this.code = resultCode.code();
        this.message = resultCode.message();
    }

 

5.異常測試處理

 1. 異常類的建立

 這裡使用的是列舉型別,當然也可以用普通class 實現介面

public enum CmsCode implements ResultCode {
    CMS_ADDPAGE_EXISTSNAME(false,24001,"頁面名稱已存在!"),
    CMS_GENERATEHTML_DATAURLISNULL(false,24002,"從頁面資訊中找不到獲取資料的url!"),
    CMS_GENERATEHTML_DATAISNULL(false,24003,"根據頁面的資料url獲取不到資料!"),
    CMS_GENERATEHTML_TEMPLATEISNULL(false,24004,"頁面模板為空!"),
    CMS_GENERATEHTML_HTMLISNULL(false,24005,"生成的靜態html為空!"),
    CMS_GENERATEHTML_SAVEHTMLERROR(false,24005,"儲存靜態html出錯!"),
    CMS_COURSE_PERVIEWISNULL(false,24007,"預覽頁面為空!");
    //操作程式碼
    boolean success;
    //操作程式碼
    int code;
    //提示資訊
    String message;
    private CmsCode(boolean success, int code, String message){
        this.success = success;
        this.code = code;
        this.message = message;
    }

    @Override
    public boolean success() {
        return success;
    }

    @Override
    public int code() {
        return code;
    }

    @Override
    public String message() {
        return message;
    }
    
    //set get 方法省略
}

 

 

2.專案使用 

if(obj !=null){
//校驗物件是否存在,已存在則丟擲異常
ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTS);
}

 

 

 

可能有些不太瞭解列舉的同學可能會奇怪怎麼這樣寫,,,,我一開始也是這樣,後來發現 

CmsCode.CMS_ADDPAGE_EXISTS  // 這句程式碼 

 

 

以上是我個人的見解,,如果有什麼不對的話,歡迎指出 ...謝謝