springboot 中關於異常的處理

       異常處理在項目中還是比較重要的,springboot 中的異常有些類似於springmvc,熟悉springmvc的朋友就不會那麼陌生了。爲什麼我們在項目中需要做全局異常處理暱,實際是可以在每一個contoller中的每一個方法中加入try catch,實現對異常的處理,但是這樣寫就會變焦麻煩,代碼也會比較冗餘,所以使用全局異常處理,在service中直接拋出異常就可以了,非常的簡單。

1.優缺點

  • 優點:將 Controller 層的異常和數據校驗的異常進行統一處理,減少模板代碼,減少編碼量,提升擴展性和可維護性。
  • 缺點:只能處理 Controller 層未捕獲(往外拋)的異常,對於 Interceptor(攔截器)層的異常,Spring 框架層的異常,就無能爲力了。
  • 對於 Interceptor(攔截器)或者spring框架等其他的異常try catch 返回自己定義的異常類。

2.首先主要講兩個註解

@ControllerAdvice 和 @ExceptionHandler

      2.1 @ControllerAdvice 註解定義全局異常處理類
            @ControllerAdvice
            public class GlobalExceptionHandler {
            }
      請確保此 GlobalExceptionHandler 類能被掃描到並裝載進 Spring 容器中。

      2.2 @ExceptionHandler 註解聲明異常處理方法
            @ControllerAdvice
            public class GlobalExceptionHandler {

                @ExceptionHandler(Exception.class)
                @ResponseBody
                String handleException(){
                     return "Exception Deal!";
                }
           }

          方法 handleException() 就會處理所有 Controller 層拋出的 Exception 及其子類的異常,這是最基本的用法了。

           如果 @ExceptionHandler 註解中未聲明要處理的異常類型,則默認爲參數列表中的異常類型。所以上面的寫法,還可以寫成這樣:

           @ControllerAdvice
           public class GlobalExceptionHandler {

                @ExceptionHandler()
                @ResponseBody
                String handleException(Exception e){
                    return "Exception Deal! " + e.getMessage();
               }
           }
 

3.附上代碼

  3.1全局異常處理

  此類中可以根據不同的異常做不同的處理

package com.example.exception;

import com.example.entity.ResultModel;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;


/**
 * 全局異常捕獲
 */

@ControllerAdvice
public class GlobalDefultExceptionHandler {

    //聲明要捕獲的異常
    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public ResultModel<String> defultExcepitonHandler(HttpServletRequest request, BizException e) {
        ResultModel<String> resultModel = new ResultModel<String>();
        if(e instanceof BizException) {
            BizException bizException = (BizException)e;
            resultModel.setMessage(bizException.getMessage());
            resultModel.setCode(bizException.getCode());
            return resultModel;
        }
        resultModel.setCode(e.getCode());
        resultModel.setMessage(e.getMessage());
        return resultModel;
    }

}

3.2自定義的異常類

package com.example.exception;

/**
 * 異常描述
 */
public class BizException extends RuntimeException{

    /**
     * 具體異常碼
     */
    protected int code;

    /**
     * 異常信息
     */
    protected String msg;

    public BizException(int code, String msgFormat, Object... args) {
        super(String.format(msgFormat, args));
        this.code = code;
        this.msg = String.format(msgFormat, args);
    }

    public BizException(int code, String msg) {
        super(String.format(msg));
        this.code = code;
        this.msg = msg;
    }

    public BizException(int code, java.lang.Exception ex) {
        super(ex.getMessage(), ex.getCause());
        this.code = code;
        this.msg = ex.getMessage();
    }

    public BizException() {
        super();
    }

    public String getMsg() {
        return msg;
    }

    public int getCode() {
        return code;
    }

    /**
     * 實例化異常
     *
     * @param msgFormat
     * @param args
     * @return
     */
    public BizException newInstance(String msgFormat, Object... args) {
        return new BizException(this.code, msgFormat, args);
    }

    public BizException(String message, Throwable cause) {
        super(message, cause);
    }

    public BizException(Throwable cause) {
        super(cause);
    }

    public BizException(String message) {
        super(message);
    }

    @Override
    public String toString(){
        return String.format("code:%s,msg:%s,RuntimeException's info:{%s}",
                this.code,
                this.msg,
                super.toString().equals("") ? "無" : super.toString());
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章