spring boot项目的全局异常

springboot中的全局异常

在我们前后端分离项目中往往都会有统一返回结果类,也正是为了在出现错误或者异常时,对前端的返回有个友好的提示,全局对全局异常的捕捉,并直接返回正确的提示信息给前端

这个就不用导入jar了

springboot 自带了一个ControllerAdvice注解 可以对异常信息进行操作

  1. 首先我们先来创建个pojo

    @Data
    public class User implements Serializable {
        private static final long serialVersionUID = 1L;
        /**
         * 编号
         */
        private int id;
        /**
         * 姓名
         */
        private String name;
        /**
         * 年龄
         */
        private int age;
    }
    
  2. 再创建一个错误信息映射的枚举

    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;
        CommonEnum(String resultCode, String resultMsg) {
            this.resultCode = resultCode;
            this.resultMsg = resultMsg;
        }
        @Override
        public String getResultCode() {
            return null;
        }
        @Override
        public String getResultMsg() {
            return null;
        }
    
  3. 创建一个baseerror接口来给后面我们所需要的异常处理类调用

    public interface BaseErrorInfoInterface {
        /**
         * 错误码
         *
         * @return
         */
        String getResultCode();
        /**
         * 错误描述
         *
         * @return
         */
        String getResultMsg();
    }
    
  4. 我们就声明一个业务异常把,也不搞什么daoException和ServiceException了

    @Data
    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;
        }
    
        @Override
        public String getMessage() {
            return errorMsg;
        }
    
        @Override
        public Throwable fillInStackTrace() {
            return this;
        }
    }
    
  5. 现在是时候把我们的全局返回类搬出来了,这里我运用到了链式编程,不懂得可以baidu,这里还定义了各种情况的返回

    @Accessors(chain = true)
    @Data
    public class ReturnResult {
        /**
         * 响应代码
         */
        private String code;
        /**
         * 响应消息
         */
        private String message;
        /**
         * 响应结果
         */
        private Object result;
    
        public ReturnResult() {
        }
        public ReturnResult(BaseErrorInfoInterface errorInfo) {
            this.code = errorInfo.getResultCode();
            this.message = errorInfo.getResultMsg();
        }
        /**
         * 成功(但是没数据)
         *
         * @return
         */
        public static ReturnResult success() {
            return success(null);
        }
        /**
         * 成功并且有数据
         *
         * @param data
         * @return
         */
        public static ReturnResult success(Object data) {
            return new ReturnResult()
                    .setCode(CommonEnum.SUCCESS.getResultCode())
                    .setMessage(CommonEnum.SUCCESS.getResultMsg())
                    .setResult(data);
        }
        /**
         * 失败(不自定义code和msg)
         */
        public static ReturnResult error(BaseErrorInfoInterface errorInfo) {
            return new ReturnResult()
                    .setCode(errorInfo.getResultCode())
                    .setMessage(errorInfo.getResultMsg())
                    .setResult(null);
        }
        /**
         * 失败(自定义code和msg)
         */
        public static ReturnResult error(String code, String message) {
            return new ReturnResult()
                    .setCode(code)
                    .setMessage(message)
                    .setResult(null);
        }
        /**
         * 失败code:-1 msg自定
         */
        public static ReturnResult error(String message) {
            return new ReturnResult()
                    .setCode("-1")
                    .setMessage(message)
                    .setResult(null);
        }
        @Override
        public String toString() {
            return "JSONObject.toJSONString(this)";
        }
    }
    
  6. 现在是我们的主角正式出场了,全局异常处理

    @ControllerAdvice
    @Slf4j
    public class GlobalExceptionHandler {
        /**
         * 处理自定义的业务异常
         *
         * @param req
         * @param e
         * @return
         */
        @ExceptionHandler(value = BizException.class)
        @ResponseBody
        public ReturnResult bizExceptionHandler(HttpServletRequest req, BizException e) {
            log.error("发生业务异常!原因是:{}", e.getErrorMsg());
            return ReturnResult.error(e.getErrorCode(), e.getErrorMsg());
        }
        /**
         * 处理空指针的异常
         *
         * @param req
         * @param e
         * @return
         */
        @ExceptionHandler(value = NullPointerException.class)
        @ResponseBody
        public ReturnResult exceptionHandler(HttpServletRequest req, NullPointerException e) {
            log.error("发生空指针异常!原因是:", e.getMessage());
            return ReturnResult.error(CommonEnum.BODY_NOT_MATCH);
        }
        /**
         * 处理其他异常
         *
         * @param req
         * @param e
         * @return
         */
        @ExceptionHandler(value = Exception.class)
        @ResponseBody
        public ReturnResult exceptionHandler(HttpServletRequest req, Exception e) {
            log.error("未知异常!原因是:", e.getMessage());
            return ReturnResult.error(CommonEnum.INTERNAL_SERVER_ERROR);
        }
    }
    
  7. 后面就可以写个controller测试了

    @RestController
    public class controller {
        @PostMapping("/user")
        public boolean insert(@RequestBody User user) {
            System.out.println("开始新增...");
            //如果姓名为空就手动抛出一个自定义的异常!
            if (user.getName() == null) {
                throw new BizException("-1", "用户姓名不能为空!");
            }
            return true;
        }
        @PutMapping("/user")
        public boolean update(@RequestBody User user) {
            System.out.println("开始更新...");
            //这里故意造成一个空指针的异常,并且不进行处理
            String str = null;
            str.equals("111");
            return true;
        }
        @DeleteMapping("/user")
        public boolean delete(@RequestBody User user) {
            System.out.println("开始删除...");
            //这里故意造成一个异常,并且不进行处理
            Integer.parseInt("abc123");
            return true;
        }
        @GetMapping("/user")
        public List<User> findByUser(User user) {
            System.out.println("开始查询...");
            List<User> userList = new ArrayList<>();
            User user2 = new User();
            user2.setId(1);
            user2.setName("xuwujing");
            user2.setAge(18);
            userList.add(user2);
            return userList;
        }
    }
    

    讲了这么多,也实现了,我们应该也大概对这个流程有个底了把,无非就是把错误捕捉友好的返回给前端,而不是直接不响应,或者抛出错误,这样是对系统的不友好。0.0

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值