SpringBoot全局異常處理

1、創(chuàng)建自定義異常類

這里我們繼承的是運行時異常類,我們可以在這里按需求定義自己想要返回的異常類型。
我們在使用時乃正,可以使用try{}catch(){}來進行自定義異常的使用。

/**
 * 自定義異常,繼承運行時異常
 * @author MyException
 */
public class BusinessException extends RuntimeException{

    private static final long serialVersionUID = 1L;
    /**
     * 自定義返回異常狀態(tài)參數(shù)
     */
    private int code;
    /**
     * 自定義返回異常狀態(tài)信息
     */
    private String errorMessage;
    /**
     * 構造方法婶博,可以自定義返回信息
     */
    public BusinessException(String errorMessage) {
        super(errorMessage);
        this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
        this.errorMessage = errorMessage;
    }
    /**
     * 構造方法瓮具,自定義返回狀態(tài)與信息
     */
    public BusinessException(Integer code, String errorMessage) {
        super(errorMessage);
        this.code = code;
        this.errorMessage = errorMessage;
    }
    /**
     * 構造方法,自己的(封裝的參數(shù))
     */
    public BusinessException(AbstractBusinessException exception) {
        super(exception.getMessage());
        this.code = exception.getCode();
        this.errorMessage = exception.getMessage();
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

}

2凡人、創(chuàng)建統(tǒng)一異常返回對象

自定義返回模型名党,方便返回的數(shù)據(jù)類型管理操作,代碼規(guī)范等
這里要注意ResUtil挠轴、AbstractBusinessException是封裝的數(shù)據(jù)類或接口传睹,便于數(shù)據(jù)的管理操作,代碼規(guī)范等
可以根據(jù)個人需求來進行本類的方法增加或刪除

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

/**
 * 自定義返回模型
 * @author MyException
 */
public class ResponseModel {

    /**
     * 操作成功返回的方法
     * ResUtil是我個人封裝的返回數(shù)據(jù)類型
     */
    public static ResponseEntity<ResUtil> success(){
        return ResponseEntity.ok(ResUtil.success());
    }

    /**
     * 操作成功返回的方法
     * @param resUtil 封裝類
     */
    public static ResponseEntity<ResUtil> success(ResUtil resUtil){
        return ResponseEntity.ok(resUtil);
    }
    /**
      * 操作錯誤返回的方法岸晦,AbstractBusinessException 也是自己寫的接口
      */
    public static ResponseEntity<ResUtil> fail(AbstractBusinessException ex){
        return ResponseEntity
                //返回服務器異常狀態(tài)
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                //返回服務器異常數(shù)據(jù)
                .body(ResUtil.fail(ex.getMessage()));
    }
}

3欧啤、創(chuàng)建Controller層異常控制器類

創(chuàng)建異称羯希控制器類@ControllerAdvice邢隧、@ExceptionHandler注解必不可少
這里我捕獲了三個異常類型,大家可以按需求進行各自的異常類型細化拋出
ExceptionEnum這是自定義的異常枚舉類

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * controller層異常統(tǒng)一管理類
 * @author MyException
 */
@Slf4j 
@ControllerAdvice
public class ExceptionControllerAdvice {
    /**
     * 這里是捕獲的頂級異常冈在,所有異常的父類
     * 當我們沒有捕獲細化異常時倒慧,系統(tǒng)或把捕獲到的異常直接在這里進行返回
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<ResUtil> errorHandler(Exception e){
        //輸出枚舉類中的自定義異常信息,再輸出異常
        log.error(ExceptionEnum.EXCEPTION_MSG.getMessage(),e);
        return ResponseModel.fail(ExceptionEnum.EXCEPTION_MSG);
    }
    /**
     * 這里是捕獲的自定義異常包券,繼承的是運行時異常類(運行時異常繼承頂級異常類)
     * 當出現(xiàn)運行時異常以及他的子類異常的時候我們會在這里進行捕獲并返回
     * 這里主要用于用戶自己拋出的異常捕獲
     */
    @ResponseBody
    @ExceptionHandler(value = BusinessException.class)
    public ResponseEntity<ResUtil> errorHandler(BusinessException ex){
        //輸出枚舉類中的自定義異常信息纫谅,再輸出異常
        log.error(ExceptionEnum.EXCEPTION_MSG.getMessage(),ex);
        return ResponseModel.fail(ExceptionEnum.EXCEPTION_MSG);
    }
    /**
     * 這里是捕獲的運算異常,繼承的是運行時異常類(運行時異常繼承頂級異常類)
     * 當出現(xiàn)運算異常的時候我們會在這里進行捕獲并返回
     * 本次測試也是使用運算異常測試
     */
    @ResponseBody
    @ExceptionHandler(value = ArithmeticException.class)
    public ResponseEntity<ResUtil> errorHandler(ArithmeticException ax){
        //輸出枚舉類中的自定義異常信息溅固,再輸出異常
        log.error(ExceptionEnum.EXCEPTION_MSG.getMessage(),ax);
        return ResponseModel.fail(ExceptionEnum.EXCEPTION_MSG);
    }
}

全局異常首先捕獲的是最小的異常付秕,當你沒有捕獲這個異常時,會捕獲他的父類異常发魄,如果這個父類異常你也沒有捕獲盹牧,那就會捕獲到爺爺類(父類的父類)俩垃,最終捕獲到Exception這個最大的異常類

4励幼、創(chuàng)建一些必備類

然后這里是我demo里面的一些必須要使用到的類

  • 異常枚舉類
/**
 * 異常枚舉類
 * @author MyException
 */
public enum ExceptionEnum implements AbstractBusinessException {
    //系統(tǒng)繁忙異常
    EXCEPTION_MSG(500,"系統(tǒng)繁忙"),
    ;

    private int code;
    private String message;

    ExceptionEnum(int code,String message){
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return this.code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

  • 抽象業(yè)務異常接口
/**
 * 抽象業(yè)務異常
 * @author MyException
 */
public interface AbstractBusinessException {

    /**
     * 獲取異常狀態(tài)碼
     * @return 數(shù)值
     */
    int getCode();

    /**
     * 獲取異常信息
     * @return 字符
     */
    String getMessage();
}

  • 統(tǒng)一返回封裝類
    這里可以更具自己的需求創(chuàng)建或修改自己需要的方法,配合使用
import lombok.Data;
import org.springframework.http.HttpStatus;

import java.util.UUID;

/**
 * 統(tǒng)一返回封裝類
 * @author MyException
 */
@Data
public class ResUtil {

    private static final long serialVersionUID = 1L;
    /**
     * 數(shù)據(jù)體
     */
    private Object data;
    /**
     * 提示消息
     */
    private String msg;
    /**
     * 總條數(shù)
     */
    private int allCount;
    /**
     * 狀態(tài)碼
     */
    private String code;
    /**
     * 毫秒級時間
     */
    private long time;
    /**
     * uuid
     */
    private String token;
    /**
     * 請求是否成功
     */
    private boolean success;
    /**
     * 請求狀態(tài)
     */
    private int is;

    private ResUtil(){}

    public static ResUtil success(){
        ResUtil res = new ResUtil();
        res.setIs(ResConstant.RET_YES);
        res.setMsg(SystemConstant.OPERATION_SUCCESS);
        res.setAllCount(0);
        res.setData("");
        res.setCode(String.valueOf(HttpStatus.OK.value()));
        res.setTime(System.currentTimeMillis());
        res.setToken(UUID.randomUUID().toString());
        res.setSuccess(true);
        return res;
    }

    public static ResUtil fail(BusinessException ex) {
        ResUtil res = new ResUtil();
        res.setIs(ResConstant.RET_NO);
        res.setMsg(ex.getErrorMessage());
        res.setAllCount(0);
        res.setData("");
        res.setCode(String.valueOf(ex.getCode()));
        res.setTime(System.currentTimeMillis());
        res.setToken(UUID.randomUUID().toString());
        res.setSuccess(false);
        return res;
    }

    public static ResUtil fail(String msg) {
        ResUtil res = new ResUtil();
        res.setIs(ResConstant.RET_NO);
        res.setMsg(msg);
        res.setAllCount(0);
        res.setData("");
        res.setCode(String.valueOf(HttpStatus.BAD_REQUEST.value()));
        res.setTime(System.currentTimeMillis());
        res.setToken(UUID.randomUUID().toString());
        res.setSuccess(false);
        return res;
    }
}

  • 系統(tǒng)常量
/**
 * 系統(tǒng)常量
 * @author MyException
 */
public class SystemConstant {

    /**
     * 請求操作成功返回提示
     */
    public static final String OPERATION_SUCCESS = "操作成功";
    /**
     * 請求操作失敗返回提示
     */
    public static final String OPERATION_FAIL = "操作失敗";
}
/**
 * 參數(shù)常量
 * @author MyException
 */
public class ResConstant {

    /**
     * 返回值--失敗
     */
    public static final int RET_NO = 0;
    /**
     * 返回值--成功
     */
    public static final int RET_YES = 1;
    /**
     * 返回值--超時
     */
    public static final int RET_OVER = 2;
}

小吾的分割線


5口柳、華麗麗的測試

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author MyException
 */
@Slf4j
@RestController
@RequestMapping("/exceptionController")
public class ExceptionController {
      /**
       * 這里直接會拋出運算異常苹粟,并且被捕獲
       */
    @GetMapping("/test1Exception")
    public ResponseEntity<ResUtil> test1Exception(){
        log.debug("**************");
        int x = 2/0;
        return ResponseModel.success();
    }
      /**
       * 這里直接會拋出自定義異常,并且被捕獲
       */
    @GetMapping("/test2Exception")
    public ResponseEntity<ResUtil> test2Exception(){
        log.debug("**************");
        try{
            int x = 2/0;
        }catch (Exception e){
            throw new BusinessException("異常111");
        }
        return ResponseModel.success();
    }
}

這里附上兩張測試截圖


運算異常捕獲測試

自定義異常測試

至此SpringBoot全局異常就寫完了跃闹,如有不懂可以加SpringBoot技術交流群14群號:719099151我是小吾嵌削,有問題可以直接在群里@我

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末毛好,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子苛秕,更是在濱河造成了極大的恐慌肌访,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艇劫,死亡現(xiàn)場離奇詭異吼驶,居然都是意外死亡,警方通過查閱死者的電腦和手機店煞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門蟹演,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人顷蟀,你說我怎么就攤上這事酒请。” “怎么了鸣个?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵羞反,是天一觀的道長。 經常有香客問我囤萤,道長苟弛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任阁将,我火速辦了婚禮膏秫,結果婚禮上,老公的妹妹穿的比我還像新娘做盅。我一直安慰自己缤削,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布吹榴。 她就那樣靜靜地躺著亭敢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪图筹。 梳的紋絲不亂的頭發(fā)上帅刀,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音远剩,去河邊找鬼扣溺。 笑死,一個胖子當著我的面吹牛瓜晤,可吹牛的內容都是我干的锥余。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼痢掠,長吁一口氣:“原來是場噩夢啊……” “哼驱犹!你這毒婦竟也來了嘲恍?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤雄驹,失蹤者是張志新(化名)和其女友劉穎佃牛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體医舆,經...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡吁脱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了彬向。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兼贡。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娃胆,靈堂內的尸體忽然破棺而出遍希,到底是詐尸還是另有隱情,我是刑警寧澤里烦,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布凿蒜,位于F島的核電站,受9級特大地震影響胁黑,放射性物質發(fā)生泄漏废封。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一丧蘸、第九天 我趴在偏房一處隱蔽的房頂上張望漂洋。 院中可真熱鬧,春花似錦力喷、人聲如沸刽漂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贝咙。三九已至,卻和暖如春拂募,著一層夾襖步出監(jiān)牢的瞬間庭猩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工陈症, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蔼水,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓爬凑,卻偏偏與公主長得像徙缴,于是被迫代替她去往敵國和親试伙。 傳聞我的和親對象是個殘疾皇子嘁信,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361