1. 程式人生 > >spring boot 全域性異常處理及自定義異常類

spring boot 全域性異常處理及自定義異常類

全域性異常處理:

定義一個處理類,使用@ControllerAdvice註解。

@ControllerAdvice註解:控制器增強,一個被@Component註冊的元件。

配合@ExceptionHandler來增強所有的@requestMapping方法。

例如:@ExceptionHandler(Exception.class)  用來捕獲@requestMapping的方法中所有丟擲的exception。

程式碼:

  1. @ControllerAdvice
  2. public class GlobalDefultExceptionHandler {
  3. //宣告要捕獲的異常
  4. @ExceptionHandler(Exception.class)
  5. @ResponseBody
  6. public String defultExcepitonHandler(HttpServletRequest request,Exception e) {
  7.     return “error”;
  8. }
  9. }

這樣,全域性異常處理類完畢。可以新增自己的邏輯。

然後還有一個問題,有的時候,我們需要業務邏輯時丟擲自定義異常,這個時候需要自定義業務異常類。

定義class:BusinessException ,使他繼承於RuntimeException.

說明:因為某些業務需要進行業務回滾。但spring的事務只針對RuntimeException的進行回滾操作。所以需要回滾就要繼承RuntimeException。

  1. public class BusinessException extends RuntimeException{
  2. }

然後,現在來稍微完善一下這個類。

當我們丟擲一個業務異常,一般需要錯誤碼和錯誤資訊。有助於我們來定位問題。

所以如下:

  1. public class BusinessException extends RuntimeException{
  2. //自定義錯誤碼
  3. private Integer code;
  4. //自定義構造器,只保留一個,讓其必須輸入錯誤碼及內容
  5. public BusinessException(int code,String msg) {
  6. super(msg);
  7. this.code = code;
  8. }
  9. public Integer getCode() {
  10. return code;
  11. }
  12. public void setCode(Integer code) {
  13. this.code = code;
  14. }
  15. }

這時候,我們發現還有一個問題,如果這樣寫,在程式碼多起來以後,很難管理這些業務異常和錯誤碼之間的匹配。所以在優化一下。

把錯誤碼及錯誤資訊,組裝起來統一管理。

定義一個業務異常的列舉。

  1. public enum ResultEnum {
  2. UNKONW_ERROR(-1,"未知錯誤"),
  3. SUCCESS(0,"成功"),
  4. ERROR(1,"失敗"),
  5. ;
  6. private Integer code;
  7. private String msg;
  8. ResultEnum(Integer code,String msg) {
  9. this.code = code;
  10. this.msg = msg;
  11. }
  12. public Integer getCode() {
  13. return code;
  14. }
  15. public String getMsg() {
  16. return msg;
  17. }
  18. }

這個時候,業務異常類:

  1. public class BusinessException extends RuntimeException{
  2. private static final long serialVersionUID = 1L;
  3. private Integer code; //錯誤碼
  4. public BusinessException() {}
  5. public BusinessException(ResultEnum resultEnum) {
  6. super(resultEnum.getMsg());
  7. this.code = resultEnum.getCode();
  8. }
  9. public Integer getCode() {
  10. return code;
  11. }
  12. public void setCode(Integer code) {
  13. this.code = code;
  14. }
  15. }

然後再修改一下全域性異常處理類:

  1. @ControllerAdvice
  2. public class GlobalDefultExceptionHandler {
  3. //宣告要捕獲的異常
  4. @ExceptionHandler(Exception.class)
  5. @ResponseBody
  6. public <T> Result<?> defultExcepitonHandler(HttpServletRequest request,Exception e) {
  7. e.printStackTrace();
  8. if(e instanceof BusinessException) {
  9. Log.error(this.getClass(),"業務異常:"+e.getMessage());
  10. BusinessException businessException = (BusinessException)e;
  11. return ResultUtil.error(businessException.getCode(), businessException.getMessage());
  12. }
  13. //未知錯誤
  14. return ResultUtil.error(-1, "系統異常:\\n"+e);
  15. }
  16. }
判斷這個是否是業務異常。和系統異常就可以分開處理了。