首頁 > 軟體

springboot 全域性例外處理和統一響應物件的處理方式

2022-06-28 18:06:01

springboot例外處理

SpringBoot 預設的例外處理機制

預設情況,SpringBoot 提供兩種不同響應方式

  • 一種是瀏覽器使用者端請求一個不存在的頁面或伺服器端異常時,SpringBoot預設會響應一個html
  • 另一種是使用postman等偵錯工具請求不存在的url或伺服器端異常時,預設返回json資訊

SpringBoot 全域性例外處理

一般我們不會將錯誤資訊返回前端,自己去try catch捕獲異常,但有個問題:每個方法都這樣捕獲異常,肯定是不合適,這是我們就需要全域性的例外處理了。

@RestController
public class ExceptionController {
    @GetMapping("exceptionA")
    public void methodA() {
        try {
            int a = 100 / 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1. 區域性例外處理

使用@EceptionHandle註解實現某個類的區域性例外處理

   @RestController
   public class ExceptionController {
   
       @GetMapping("exceptionA")
       public void methodA() {
           int a = 100 / 0;
       }
   
       /**
        * 區域性例外處理
        */
       @ExceptionHandler(Exception.class)
       public String exHandler(Exception e) {
           // 判斷髮生異常的型別是除0異常則做出響應
           if (e instanceof ArithmeticException) {
               return "發生了除0異常";
           }
           // 未知的異常做出響應
           return "發生了未知異常";
       }
   }

2. 全域性例外處理

使用@ControllerAdvice +@ExceptionHandler註解實現全域性例外處理

自定義一個異常類

@RestControllerAdvice
public class DefaultException {
​
    @ExceptionHandler({NullPointerException.class})
    public String exception(NullPointerException exception) {
        return "空指標異常";
​
    }
​
    @ExceptionHandler({IndexOutOfBoundsException.class})
    public String exception(IndexOutOfBoundsException exception) {
        return "陣列越界異常";
    }
}

增加一個異常方法測試,由於區域性異常優先順序更高先註釋掉了

@RestController
public class ExceptionController {
​
    @GetMapping("exceptionA")
    public void methodA() {
        int a = 100 / 0;
    }
​
    @GetMapping("exceptionB")
    public void methodB() {
        List list = new ArrayList<>();
        System.out.println(list.get(0));
    }
​
    /**
     * 區域性例外處理
     */
    //@ExceptionHandler(Exception.class)
    //public String exHandler(Exception e) {
    //    // 判斷髮生異常的型別是除0異常則做出響應
    //    if (e instanceof ArithmeticException) {
    //        return "發生了除0異常";
    //    }
    //    // 未知的異常做出響應
    //    return "發生了未知異常";
    //}
}

全域性異常註解已生效

自定義異常

自定義異常只需要繼承exception類或其子類

@Data
@NoArgsConstructor
public class CustomException extends Exception {
​
    private static final long serialVersionUID = 1L;
​
    private Integer code;
​
    private String mes;
​
    /**
     * @param code 狀態碼
     * @param msg  異常返回資訊
     * @description 構造器
     */
    public CustomException(Integer code, String msg) {
        super(msg);
        this.code = code;
    }
}

使用時可以直接丟擲異常物件

@GetMapping("exceptionC")
public void methodC() throws CustomException {
    int a = 1;
    if (a == 1) {
        throw new CustomException(10086, "自定義異常");
    }
}

統一響應物件

實際開發中我們需要封裝統一的響應物件,區分狀態碼和資訊,以便前端處理。

定義統一的響應物件

一般包含狀態碼,錯誤資訊,資料等。

自定義一些方法用來返回資訊,比如我定義的success(),failed()方法

@Data
@NoArgsConstructor
@AllArgsConstructor
public class R<T> {
    /**
     * 返回狀態碼
     */
    private Integer code;
    /**
     * 返回資訊
     */
    private String msg;
    /**
     * 資料
     */
    private T data;
​
    public static R success() {
        return new R(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), null);
    }
​
    public static R success(Object data) {
        return new R(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), data);
    }
​
    public static R failed() {
        return new R(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg(), null);
    }
​
    public static R failed(String msg) {
        return new R(ResultCode.FAILED.getCode(), msg, null);
    }
​
    public static R failed(int code, String msg) {
        return new R(code, msg, null);
    }
}

列舉資訊

列舉一些常用的狀態資訊

我就舉個例子,只列舉2個,根據需要去自定義

@NoArgsConstructor
@AllArgsConstructor
public enum ResultCode {
​
    SUCCESS(200, "請求成功"),
    FAILED(500, "伺服器錯誤");
​
    private int code;
    private String msg;
​
    public int getCode() {
        return code;
    }
​
    public void setCode(int code) {
        this.code = code;
    }
​
    public String getMsg() {
        return msg;
    }
​
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

響應物件

使用時直接返回定義的物件型別就行了,將定義的全域性異常返回型別也改成統一的響應物件

@RestControllerAdvice
public class DefaultException {
    @ExceptionHandler({CustomException.class})
    public R exception(CustomException e) {
        return R.failed(e.getCode(),e.getMessage());
    }

    @ExceptionHandler({Exception.class})
    public R exception(Exception e) {
        return R.failed(e.getMessage());
    }
}

全域性異常和響應物件的簡單介紹就這樣了,歡迎補充指正。

gitee地址:gitee.com/rainscloud/…

到此這篇關於springboot 全域性例外處理和統一響應物件的文章就介紹到這了,更多相關springboot全域性例外處理內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com