<thead id="rrjt3"></thead>
      <progress id="rrjt3"><dfn id="rrjt3"></dfn></progress>

      <em id="rrjt3"></em>

        <address id="rrjt3"><ins id="rrjt3"><dfn id="rrjt3"></dfn></ins></address>
          <i id="rrjt3"></i>

        Spring Boot中的全局異常處理

        時間:2022-10-09 23:17:29 類型:JAVA
        字號:    

          在項目開發過程中,不管是對底層數據庫的操作過程,還是業務層的處理過程,還是控制層的處理過程,都不可避免會遇到各種可預知的、不可預知的異常需要處理。如果對每個過程都單獨作異常處理,那系統的代碼耦合度會變得很高,此外,開發工作量也會加大而且不好統一,這也增加了代碼的維護成本。

          針對這種實際情況,我們需要將所有類型的異常處理從各處理過程解耦出來,這樣既保證了相關處理過程的功能單一,也實現了異常信息的統一處理和維護。同時,我們也不希望直接把異常拋給用戶,應該對異常進行處理,對錯誤信息進行封裝,然后返回一個友好的信息給用戶。

                方法如下:

          1. 定義返回的統一 json 結構

        import lombok.Data;
        
        @Data
        public class EJson {
            /**
             * 異常碼
             */
            protected String code;
            /**
             * 異常信息
             */
            protected String msg;
            public EJson() {
                this.code = "200";
                this.msg = "操作成功";
            }
            public EJson(String code, String msg) {
                this.code = code;
                this.msg = msg;
            }
        }

          2. 處理系統異常

          新建一個 GlobalExceptionHandler 全局異常處理類,

                @ControllerAdvice 注解即可攔截項目中拋出的異常

                @ResponseBody 注解是為了異常處理完之后給調用方輸出一個 json 格式的封裝 數據。

        如下:

                第一個攔截異常:參數缺失的時候,會拋出 HttpMessageNotReadableException

                第二個攔截異常:空指針異常,   NullPointerException

               以此類推: 可以定義更多的異常.....................

                最后把再定義一個 Exception異常, 前邊沒有被攔截的異常,統統都會在這里被攔截

               Exception 異常是父類,所有異常都會繼承該異常,所以我們可以直接攔截 Exception 異常,一勞永逸

        @ControllerAdvice
        @ResponseBody
        public class GlobalExceptionHandler {
            // 打印log
            private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
            /**
             * 缺少請求參數異常
             * @param ex HttpMessageNotReadableException
             * @return
             */
            @ExceptionHandler(MissingServletRequestParameterException.class)
            @ResponseStatus(value = HttpStatus.BAD_REQUEST)
            public EJson handleHttpMessageNotReadableException(
                    MissingServletRequestParameterException ex) {
                    logger.error("缺少請求參數,{}", ex.getMessage());
                return new EJson("400", "缺少必要的請求參數");
            }
        
            /**
             * 空指針異常
             * @param ex NullPointerException
             * @return
             */
            @ExceptionHandler(NullPointerException.class)
            @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
            public EJson handleTypeMismatchException(NullPointerException ex) {
                logger.error("空指針異常,{}", ex.getMessage());
                return new EJson("500", "空指針異常了");
            }
        
            /**
             * 系統異常 預期以外異常
             * @param ex
             * @return
             */
            @ExceptionHandler(Exception.class)
            @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
            public EJson handleUnexpectedServer(Exception ex) {
                logger.error("系統異常:", ex);
                return new EJson("500", "系統發生異常,請聯系管理員");
            }
        }

        定義控制器做個測試:

        @RestController
            @RequestMapping("/exception")
        public class ExceptionController {
                private static final Logger logger =
                        LoggerFactory.getLogger(ExceptionController.class);
                @PostMapping("/test")
                public EJson test(@RequestParam("name") String name,
                                  @RequestParam("sex") String sex) {
                    logger.info("name:{}", name);
                    logger.info("sex:{}", sex);
                    return new EJson();
                }
        
                @RequestMapping("/null")
                public EJson test1(String name,String sex){
                    if(sex.equals("男")){
                        logger.info("性別:{}",sex);
                    }
                    return new EJson();
                }
                @RequestMapping("/byzero")
                public EJson test2(){
                    int result = 1 / 0;
                    return new EJson();
                }
            }

        通過Postman訪問做個測試

        1.jpg2.jpg

        3.jpg

        黄网站免费 <