溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java怎么實現統一異常處理

發布時間:2021-06-21 10:24:34 來源:億速云 閱讀:505 作者:小新 欄目:開發技術

小編給大家分享一下java怎么實現統一異常處理,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

對于Dao層 和Service產生的異常要一直網上拋,直至Controller層,但是對于controller層不能處理的異常也不能直接拋給前端。

為什么不能在service處理異常?

答:Service 層往往涉及數據庫事務,出現異常同樣不適合捕獲,否則事務無法自動回滾。此外 Service 層涉及業務邏輯,有些業務邏輯執行中遇到業務異常,可能需要在異常后轉入分支業務流程。如果業務異常都被框架捕獲了,業務功能就會不正常?!?strong>引用:極客時間的Java業務開發常見錯誤100例】

實現統一異常處理:

在spring框架下實現一個異常處理的類,用 @RestControllerAdvice + @ExceptionHandler

進行修飾:

即@RestControllerAdvice默認會攔截 controller類上拋出的不能處理的異常

一個全局異常處理類需要處理三類異常: 1.業務類異常,2.運行時異常 ,3.Error

1.運行時異常

/**
 * @創建人: liup
 * @創建時間: 2021/6/18
 * @描述   全局異常捕獲處理類
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
 
    
    /**
    * @Author:  liup
    * @date:  2021/6/18 14:34
      方法實現說明:  攔截運行時異常
    */
    @ExceptionHandler(value = RuntimeException.class)
    public R runtimeExceptionHandle(RuntimeException e){
        log.error("捕捉到運行時異常",e);
        return R.failed("未知錯誤");
    }
}

目前僅是攔截運行時異常

R 是返回的消息體:

java怎么實現統一異常處理

那如果不使用GlobalExceptionHandler,會報出什么錯誤呢?

這個錯誤是在service層拋出的,當從redis 通過key獲取一個已刪除的value時,redis返回的是null,但是我沒有判斷這個value是否為null,就將其打印出來:

log.info(authInfoVo.toString());

java怎么實現統一異常處理

注意:這是要返回給前端的,msg的內容,是對用戶十分不友好的。

2.Error

RuntimeException只是異常中的一個類,不能包含所有的異常體系,還有一大類是叫Error(系統級異常),所以需要有一個兜底的異常捕獲:

/**
    * @Author:  liup
    * @date:  2021/6/18 15:01
      方法實現說明: 捕獲系統級異常
    */
    @ExceptionHandler(value = Throwable.class)
    public R  throwableHandle(Throwable th){
        log.error("捕捉到Throwable異常",th);
        return R.failed("系統異常");
    }

和上面那個運行時異常同時存在 。

3.業務類異常

【自己定義的異?!?/p>

首先創建業務異常類

/**
 * @創建人: liup
 * @創建時間: 2021/6/18
 * @描述  業務類異常
 */
public class BusinessException extends RuntimeException{
 
      @Getter
       private final String code;
 
      /**
      * @Author:  liup
      * @date:  2021/6/18 15:10
        方法實現說明:  根據消息碼【可用枚舉類】 構造業務類異常
      */
    public BusinessException(String code) {
        this.code = code;
    }
 
    /**
    * @Author:  liup
    * @date:  2021/6/18 15:08
      方法實現說明:  自定義消息體構造業務類異常
    */
    public BusinessException(String code,String message) {
        super(message);
        this.code = code;
    }
 
    /**
    * @Author:  liup
    * @date:  2021/6/18 15:09
      方法實現說明:  根據異常 構造業務類異常
    */
    public BusinessException(String code,Throwable cause) {
        super(cause);
        this.code = code;
    }
 
}

三種異常攔截同時存在;

/**
 * @創建人: liup
 * @創建時間: 2021/6/18
 * @描述   全局異常捕獲處理類
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
 
 
    /**
    * @Author:  liup
    * @date:  2021/6/18 15:14
      方法實現說明:  攔截業務類異常
    */
    @ExceptionHandler(value = BusinessException.class)
    public R businessExceptionHandle(BusinessException e){
 
        log.error("捕獲業務類異常:",e);
        return R.failed("業務類異常:"+e.getMessage());
    }
 
 
    /**
    * @Author:  liup
    * @date:  2021/6/18 14:34
      方法實現說明:  攔截運行時異常
//    */
    @ExceptionHandler(value = RuntimeException.class)
    public R runtimeExceptionHandle(RuntimeException e){
        log.error("捕捉到運行時異常",e);
        return R.failed("未知錯誤:");
    }
 
    /**
    * @Author:  liup
    * @date:  2021/6/18 15:01
      方法實現說明: 捕獲系統級異常
    */
    @ExceptionHandler(value = Throwable.class)
    public R  throwableHandle(Throwable th){
        log.error("捕捉到Throwable異常",th);
        return R.failed("系統異常");
    }
}

4.對服務器友好:

以上是對前端友好,但是在服務器上,不是容易定位錯誤,

但是若是在參數上添加上HttpServletRequest req, HandlerMethod method,就很容易定位到錯誤

 private static int GENERIC_SERVER_ERROR_CODE = 2000;
    private static String GENERIC_SERVER_ERROR_MESSAGE = "服務器忙,請稍后再試";
 
    @ExceptionHandler
    public R handle(HttpServletRequest req, HandlerMethod method, Exception ex) {
        if (ex instanceof BusinessException) {
            BusinessException exception = (BusinessException) ex;
            log.warn(String.format("訪問 %s -> %s 出現業務異常!", req.getRequestURI(), method.toString()), ex);
            return R.failed(GENERIC_SERVER_ERROR_MESSAGE);
        } else if (ex instanceof RuntimeException){
            log.error(String.format("訪問 %s -> %s 出現運行時異常!", req.getRequestURI(), method.toString()), ex);
            return R.failed(GENERIC_SERVER_ERROR_MESSAGE);
        }
 
        else {
            log.error(String.format("訪問 %s -> %s 出現系統異常!", req.getRequestURI(), method.toString()), ex);
            return R.failed(GENERIC_SERVER_ERROR_MESSAGE);
        }
    }

java怎么實現統一異常處理

以上是“java怎么實現統一異常處理”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女