• SpringBoot全局异常处理


    1.前言

    虽然SpringBoot已经提供了异常处理机制,但是这种方式不够灵活。可以根据其异常处理机制进行优化,自定义全局异常处理。

    2.实战演练

    2.1环境准备

    SpringBoot版本:2.3.4.RELEASE

    pom.xml需要的依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.66</version>
    </dependency>

    2.2代码实现

    1)首先定义一个基础的接口类,该接口由自定义的错误描述枚举类实现

    /***
     * 错误信息的基类接口
     */
    public interface BaseErrorInfoInterface {
        /**
         * 错误码
         */
        String getResultCode();
    
        /**
         * 错误描述
         */
        String getResultMsg();
    }

    2)自定义一个枚举类,枚举可能出现的异常信息

    /**
     * 枚举类
     */
    @AllArgsConstructor
    public enum CommonEnum implements BaseErrorInfoInterface {
    
        // 数据操作错误定义
        SUCCESS("200", "成功!"),
        BODY_NOT_MATCH("400", "请求的数据格式不符!"),
        SIGNATURE_NOT_MATCH("401", "请求的数字签名不匹配!"),
        NOT_FOUND("404", "未找到该资源!"),
        INTERNAL_SERVER_ERROR("500", "服务器内部错误!"),
        SERVER_BUSY("503", "服务器正忙,请稍后再试!");
    
        /**
         * 错误码
         */
        private String resultCode;
    
        /**
         * 错误描述
         */
        private String resultMsg;
    
        /**
         * 重写接口的方法,返回信息
         *
         * @return
         */
        @Override
        public String getResultCode() {
            return resultCode;
        }
    
        @Override
        public String getResultMsg() {
            return resultMsg;
        }
    }

    3)自定义一个异常类,用于处理在业务操作过程中可能出现的异常

    /**
     * 自定义异常类
     */
    @Setter
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    public class MyException extends RuntimeException{
    
        /**
         * 错误码
         */
        protected String errorCode;
        /**
         * 错误信息
         */
        protected String errorMsg;
    
    
        public MyException(String errorMsg) {
            super(errorMsg);
            this.errorMsg = errorMsg;
        }
    
        public MyException(String errorCode, String errorMsg, Throwable cause) {
            super(errorCode, cause);
            this.errorCode = errorCode;
            this.errorMsg = errorMsg;
        }
    
        @Override
        public synchronized Throwable fillInStackTrace() {
            return this;
        }
    }

    4)为了数据统一格式返回,自定义一个数据的返回类

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class ResultBody {
        /**
         * 响应代码
         */
        private String code;
    
        /**
         * 响应消息
         */
        private String message;
    
        /**
         * 响应结果
         */
        private Object result;
    
        public ResultBody(BaseErrorInfoInterface errorInfo) {
            this.code = errorInfo.getResultCode();
            this.message = errorInfo.getResultMsg();
        }
    
        /**
         * 成功
         *
         * @return
         */
        public static ResultBody success() {
            return success(null);
        }
    
        /**
         * 成功
         *
         * @param data
         * @return
         */
        public static ResultBody success(Object data) {
            ResultBody rb = new ResultBody();
            rb.setCode(CommonEnum.SUCCESS.getResultCode());
            rb.setMessage(CommonEnum.SUCCESS.getResultMsg());
            rb.setResult(data);
            return rb;
        }
    
        /**
         * 失败
         */
        public static ResultBody error(BaseErrorInfoInterface errorInfo) {
            ResultBody rb = new ResultBody();
            rb.setCode(errorInfo.getResultCode());
            rb.setMessage(errorInfo.getResultMsg());
            rb.setResult(null);
            return rb;
        }
    
        /**
         * 失败
         */
        public static ResultBody error(String code, String message) {
            ResultBody rb = new ResultBody();
            rb.setCode(code);
            rb.setMessage(message);
            rb.setResult(null);
            return rb;
        }
    
        /**
         * 失败
         */
        public static ResultBody error(String message) {
            ResultBody rb = new ResultBody();
            rb.setCode("-1");
            rb.setMessage(message);
            rb.setResult(null);
            return rb;
        }
    
        @Override
        public String toString() {
            return JSONObject.toJSONString(this);
        }
    }

    5)自定义全局异常处理类,用于捕获并处理所有的异常

    @ControllerAdvice
    @Slf4j
    @RestController
    public class GlobalExceptionHandler {
    
        /**
         * 处理自定义的业务异常
         *
         * @param e
         * @return
         */
        @ExceptionHandler(value = MyException.class)
        public ResultBody bizExceptionHandler(MyException e) {
            log.error("发生业务异常!原因是:{}", e.getErrorMsg());
            return ResultBody.error(e.getErrorCode(), e.getErrorMsg());
        }
    
        /**
         * 处理空指针的异常
         *
         * @param e
         * @return
         */
        @ExceptionHandler(value = NullPointerException.class)
        public ResultBody exceptionHandler(NullPointerException e) {
            log.error("发生空指针异常!原因是:", e);
            return ResultBody.error(CommonEnum.BODY_NOT_MATCH);
        }
    
        /**
         * 处理其他异常
         *
         * @param e
         * @return
         */
        @ExceptionHandler(value = Exception.class)
        public ResultBody exceptionHandler(Exception e) {
            log.error("未知异常!原因是:", e);
            return ResultBody.error(CommonEnum.INTERNAL_SERVER_ERROR);
        }
    }

    6)新建一个controller即可,用于测试

    @RestController
    @RequestMapping("/test")
    public class TestController {
    
        @GetMapping("/get")
        public String test() {
            int i = 10 / 0;
            return "hello";
        }
    
        @GetMapping("/get2")
        public String test2(String str) {
            return str.toLowerCase();
        }
    
        @PostMapping("add")
        public String test3(@RequestBody JSONObject json) {
            if (json.get("name") == null) {
                throw new MyException("-1", "姓名不能为空");
            }
            return json.get("name") + " ****";
        }
    }

    7)使用postman分别对三个接口进行访问

    访问localhost:8080/test/get,返回结果如下图:

    访问localhost:8080/test/get2,不传递参数,如下图:

    访问localhost:8080/test/get2?str=123,如下图:

    访问localhost:8080/test/add,name的值是null,如下图:

    访问localhost:8080/test/add,name的值不为null,如下图: 

    就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
  • 相关阅读:
    说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
    利用CSS3实现页面淡入动画特效
    ajax
    jQuery弹性滑动导航菜单实现思路及代码
    angular 管理后台
    jq简单选项卡
    按钮60秒倒计时
    jq倒计时
    angular ui-route
    flex弹性布局
  • 原文地址:https://www.cnblogs.com/zys2019/p/14654728.html
Copyright © 2020-2023  润新知