1. Spring Boot項(xiàng)目優(yōu)雅的全局異常處理方式(全網(wǎng)最新)

        共 17016字,需瀏覽 35分鐘

         ·

        2021-04-25 10:04

        點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

        優(yōu)質(zhì)文章,第一時間送達(dá)

        前言

        在日常項(xiàng)目開發(fā)中,異常是常見的,但是如何更高效的處理好異常信息,讓我們能快速定位到BUG,是很重要的,不僅能夠提高我們的開發(fā)效率,還能讓你代碼看上去更舒服,SpringBoot的項(xiàng)目已經(jīng)對有一定的異常處理了,但是對于我們開發(fā)者而言可能就不太合適了,因此我們需要對這些異常進(jìn)行統(tǒng)一的捕獲并處理。


        一、全局異常處理方式一

        SpringBoot中,@ControllerAdvice 即可開啟全局異常處理,使用該注解表示開啟了全局異常的捕獲,我們只需在自定義一個方法使用@ExceptionHandler注解然后定義捕獲異常的類型即可對這些捕獲的異常進(jìn)行統(tǒng)一的處理。

        1.1 自定義全局異常類

        /**
         * @description: 自定義異常處理
         * @author: DT
         * @date: 2021/4/19 21:17
         * @version: v1.0
         */
        @ControllerAdvice
        public class MyExceptionHandler {

            @ExceptionHandler(value =Exception.class)
            @ResponseBody
            public String exceptionHandler(Exception e){
                System.out.println("全局異常捕獲>>>:"+e);
                return "全局異常捕獲,錯誤原因>>>"+e.getMessage();
            }
        }

        1.2 手動拋出異常

         @GetMapping("/getById/{userId}")
        public CommonResult<User> getById(@PathVariable Integer userId){
            // 手動拋出異常
            int a = 10/0;
            return CommonResult.success(userService.getById(userId));
        }

        1.3 測試打印



        很顯然這樣的用戶體驗(yàn)效果是極差的,雖然這種能夠讓我們知道異常的原因,但是在很多的情況下來說,可能還是不夠人性化,不符合我們的要求。

        二、全局異常處理方式二

        2.1 定義基礎(chǔ)接口類

        /**
         * @description: 服務(wù)接口類
         * @author: DT
         * @date: 2021/4/19 21:39
         */
        public interface BaseErrorInfoInterface {

            /**
             *  錯誤碼
             * @return
             */
            String getResultCode();

            /**
             * 錯誤描述
             * @return
             */
            String getResultMsg();
        }

        2.2 定義枚舉類

        /**
         * @description: 異常處理枚舉類
         * @author: DT
         * @date: 2021/4/19 21:41
         * @version: v1.0
         */
        public enum ExceptionEnum implements BaseErrorInfoInterface{
            
            // 數(shù)據(jù)操作錯誤定義
            SUCCESS("2000""成功!"),
            BODY_NOT_MATCH("4000","請求的數(shù)據(jù)格式不符!"),
            SIGNATURE_NOT_MATCH("4001","請求的數(shù)字簽名不匹配!"),
            NOT_FOUND("4004""未找到該資源!"),
            INTERNAL_SERVER_ERROR("5000""服務(wù)器內(nèi)部錯誤!"),
            SERVER_BUSY("5003","服務(wù)器正忙,請稍后再試!");

            /**
             * 錯誤碼
             */
            private final String resultCode;

            /**
             * 錯誤描述
             */
            private final String resultMsg;

            ExceptionEnum(String resultCode, String resultMsg) {
                this.resultCode = resultCode;
                this.resultMsg = resultMsg;
            }

            @Override
            public String getResultCode() {
                return resultCode;
            }

            @Override
            public String getResultMsg() {
                return resultMsg;
            }
        }

        2.3 自定義異常類

        /**
         * @description: 自定義異常類
         * @author: DT
         * @date: 2021/4/19 21:44
         * @version: v1.0
         */
        public class BizException extends RuntimeException{

            private static final long serialVersionUID = 1L;

            /**
             * 錯誤碼
             */
            protected String errorCode;
            /**
             * 錯誤信息
             */
            protected String errorMsg;

            public BizException() {
                super();
            }

            public BizException(BaseErrorInfoInterface errorInfoInterface) {
                super(errorInfoInterface.getResultCode());
                this.errorCode = errorInfoInterface.getResultCode();
                this.errorMsg = errorInfoInterface.getResultMsg();
            }

            public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {
                super(errorInfoInterface.getResultCode(), cause);
                this.errorCode = errorInfoInterface.getResultCode();
                this.errorMsg = errorInfoInterface.getResultMsg();
            }

            public BizException(String errorMsg) {
                super(errorMsg);
                this.errorMsg = errorMsg;
            }

            public BizException(String errorCode, String errorMsg) {
                super(errorCode);
                this.errorCode = errorCode;
                this.errorMsg = errorMsg;
            }

            public BizException(String errorCode, String errorMsg, Throwable cause) {
                super(errorCode, cause);
                this.errorCode = errorCode;
                this.errorMsg = errorMsg;
            }


            public String getErrorCode() {
                return errorCode;
            }

            public void setErrorCode(String errorCode) {
                this.errorCode = errorCode;
            }

            public String getErrorMsg() {
                return errorMsg;
            }

            public void setErrorMsg(String errorMsg) {
                this.errorMsg = errorMsg;
            }

            @Override
            public Throwable fillInStackTrace() {
                return this;
            }
        }

        2.4 自定義數(shù)據(jù)傳輸

        /**
         * @description: 自定義數(shù)據(jù)傳輸
         * @author: DT
         * @date: 2021/4/19 21:47
         * @version: v1.0
         */
        public class ResultResponse {
            /**
             * 響應(yīng)代碼
             */
            private String code;

            /**
             * 響應(yīng)消息
             */
            private String message;

            /**
             * 響應(yīng)結(jié)果
             */
            private Object result;

            public ResultResponse() {
            }

            public ResultResponse(BaseErrorInfoInterface errorInfo) {
                this.code = errorInfo.getResultCode();
                this.message = errorInfo.getResultMsg();
            }

            public String getCode() {
                return code;
            }

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

            public String getMessage() {
                return message;
            }

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

            public Object getResult() {
                return result;
            }

            public void setResult(Object result) {
                this.result = result;
            }

            /**
             * 成功
             *
             * @return
             */
            public static ResultResponse success() {
                return success(null);
            }

            /**
             * 成功
             * @param data
             * @return
             */
            public static ResultResponse success(Object data) {
                ResultResponse rb = new ResultResponse();
                rb.setCode(ExceptionEnum.SUCCESS.getResultCode());
                rb.setMessage(ExceptionEnum.SUCCESS.getResultMsg());
                rb.setResult(data);
                return rb;
            }

            /**
             * 失敗
             */
            public static ResultResponse error(BaseErrorInfoInterface errorInfo) {
                ResultResponse rb = new ResultResponse();
                rb.setCode(errorInfo.getResultCode());
                rb.setMessage(errorInfo.getResultMsg());
                rb.setResult(null);
                return rb;
            }

            /**
             * 失敗
             */
            public static ResultResponse error(String code, String message) {
                ResultResponse rb = new ResultResponse();
                rb.setCode(code);
                rb.setMessage(message);
                rb.setResult(null);
                return rb;
            }

            /**
             * 失敗
             */
            public static ResultResponse error( String message) {
                ResultResponse rb = new ResultResponse();
                rb.setCode("-1");
                rb.setMessage(message);
                rb.setResult(null);
                return rb;
            }

            @Override
            public String toString() {
                return JSONObject.toJSONString(this);
            }

        }

        2.5 自定義全局異常處理

        /**
         * @description: 自定義異常處理
         * @author: DT
         * @date: 2021/4/19 21:51
         * @version: v1.0
         */
        @ControllerAdvice
        public class GlobalExceptionHandler {
            
            private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

            /**
             * 處理自定義的業(yè)務(wù)異常
             * @param req
             * @param e
             * @return
             */
            @ExceptionHandler(value = BizException.class)
            @ResponseBody
            public ResultResponse bizExceptionHandler(HttpServletRequest req, BizException e){
                logger.error("發(fā)生業(yè)務(wù)異常!原因是:{}",e.getErrorMsg());
                return ResultResponse.error(e.getErrorCode(),e.getErrorMsg());
            }

            /**
             * 處理空指針的異常
             * @param req
             * @param e
             * @return
             */
            @ExceptionHandler(value =NullPointerException.class)
            @ResponseBody
            public ResultResponse exceptionHandler(HttpServletRequest req, NullPointerException e){
                logger.error("發(fā)生空指針異常!原因是:",e);
                return ResultResponse.error(ExceptionEnum.BODY_NOT_MATCH);
            }

            /**
             * 處理其他異常
             * @param req
             * @param e
             * @return
             */
            @ExceptionHandler(value =Exception.class)
            @ResponseBody
            public ResultResponse exceptionHandler(HttpServletRequest req, Exception e){
                logger.error("未知異常!原因是:",e);
                return ResultResponse.error(ExceptionEnum.INTERNAL_SERVER_ERROR);
            }
        }

        2.6 測試代碼

        @PostMapping("/add")
        public boolean add(@RequestBody User user) {
            //如果姓名為空就手動拋出一個自定義的異常!
            if(user.getName()==null){
                throw  new BizException("-1","用戶姓名不能為空!");
            }
            return true;
        }

         @PutMapping("/update")
        public boolean update(@RequestBody User user) {
            //這里故意造成一個空指針的異常,并且不進(jìn)行處理
            String str = null;
            str.equals("111");
            return true;
        }


         @DeleteMapping("/delete")
        public boolean delete(@RequestBody User user)  {
            //這里故意造成一個異常,并且不進(jìn)行處理
            Integer.parseInt("abc123");
            return true;
        }

        如果我們想捕獲這個類型轉(zhuǎn)換異常,是不是再添加一個遺產(chǎn)處理方法就可了。

        /**
        * 處理類型轉(zhuǎn)換異常
         * @param req
         * @param e
         * @return
         */
        @ExceptionHandler(value = NumberFormatException.class)
        @ResponseBody
        public ResultResponse exceptionHandler(HttpServletRequest req, NumberFormatException e){
            logger.error("發(fā)生類型轉(zhuǎn)換異常!原因是:",e);
            return ResultResponse.error(ExceptionEnum.PARAMS_NOT_CONVERT);
        }

        PARAMS_NOT_CONVERT("4002","類型轉(zhuǎn)換不對!"),

        自定義全局異常處理除了可以處理上述的數(shù)據(jù)格式之外,也可以處理頁面的跳轉(zhuǎn),只需在新增的異常方法的返回處理上填寫該跳轉(zhuǎn)的路徑并不使用ResponseBody 注解即可。

        總結(jié)

        異常處理,能夠減少代碼的重復(fù)度和復(fù)雜度,有利于代碼的維護(hù),并且能夠快速定位到BUG,大大提高我們的開發(fā)效率。

        ————————————————

        版權(quán)聲明:本文為CSDN博主「DT~」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

        原文鏈接:

        https://blog.csdn.net/qq_41107231/article/details/115874974





        粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

        ??????

        ??長按上方微信二維碼 2 秒


        感謝點(diǎn)贊支持下哈 

        瀏覽 121
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 精品人妻一区二区 | 人人草超碰| 五月天超碰 | 久草91 | 国产无遮挡AAA片爽爽 |