美文网首页
动手写个java快速开发框架-(4)统一异常处理

动手写个java快速开发框架-(4)统一异常处理

作者: monkey01 | 来源:发表于2018-09-11 16:09 被阅读368次

    作为一个开发框架当然稍不了异常的统一处理,今天我们就在MkFramework中加入统一异常处理模块。大家在日常开发过程中,对于一些初级开发经常喜欢将代码框在try代码块中,然后在catch中进行异常捕获,但很多都只是在捕获了之后只是进行简单的print错误堆栈信息,这样就会导致系统报错了,但是我们在日志中看不到抛出的异常信息,或者是有些自认为可以进行处理的错误,其实没有处理成功,所以很多框架都加入了统一异常处理机制,这样就可以让所有的错误处理集中在一个地方进行处理,在业务代码开发过程中,遇到错误只需要进行throw就可以了,由上层统一进行拦截处理,返回给调用方。

    对于一个框架中,当然也要有错误码的统一管理,这里我们使用了自定义错误码,并将错误码定义在了错误码枚举类中,当然如果你的系统比较庞大,错误码非常多,并且要实现错误码的动态调整,那么也可以将错误码存在数据库中,启动后放到内存缓存,这里为了方便大家理解只是提前将错误码定义在了枚举类中。

    所有的错误码定义和错误异常处理都放在了common.exception包中。

    我们定义的错误类为MkException,对于我们业务中的错误都可以使用自定义异常类,对于java runtime异常或者Error还是建议不做过多的封装,这样便于查询问题。

    public class MkException extends RuntimeException {
        private static final long serialVersionUID = 1L;
        
        private String returnMsg;
        /**
         * returnCode 表示HOP内部错误码
         */
        private String returnCode = "999999";
        private String errorMsg;
    
        /**
         * errorCode 表示后台系统返回错误码
         */
        private String errorCode = "999999";
        //...省略N个重载的构造函数
        public MkException(String returnMsg, String returnCode, String errorMsg, String errorCode) {
            super(returnMsg);
            this.returnMsg = returnMsg;
            this.returnCode = returnCode;
            this.errorMsg = errorMsg;
            this.errorCode = errorCode;
        }
    
        public MkException(String returnMsg, String returnCode, String errorMsg, String errorCode, Throwable e) {
            super(returnMsg, e);
            this.returnMsg = returnMsg;
            this.returnCode = returnCode;
            this.errorMsg = errorMsg;
            this.errorCode = errorCode;
        }
    
        public MkException(ResultCode resultCode, Throwable e) {
            super(resultCode.getMessage(), e);
            this.errorMsg = resultCode.getMessage();
            this.errorCode = resultCode.getCode();
        }
    
        public MkException(ResultCode resultCode) {
            this.errorMsg = resultCode.getMessage();
            this.errorCode = resultCode.getCode();
        }
    //...省略setter、getter
    }
    
    public enum ResultCode {
        //检查输入项不能为空错误码
        IS_NOT_BLANK_ERROR("999001", "请检查输入项,不能为空"),
        SUCCESS("000000", "success"),
        UNKNOW_ERROR("999999","系统未知异常"),
    //省略其他错误码定义
    
        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;
        }
    
        private String code;
        private String message;
    
        private ResultCode(String code, String message) {
            this.code = code;
            this.message = message;
        }
    
    }
    

    因为我们使用的是Spring框架,所以我们可以通过RestControllerAdvice对所有在最上层controller中进行统一拦截,在spring中实现这样的拦截需要自定义类继承自RestControllerAdvice,当然在spring4.0以后的版本可以通过@RestControllerAdvice注解来实现定义类,然后在类中实现异常处理,对于异常处理的方法需要添加@ExceptionHandler(xxxException.class)注解来表示该方法处理哪一类异常。

    @RestControllerAdvice
    public class MkExceptionHandler {
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        private final static String NO_URL_FOUND = "404";
    
        /**
         * 处理自定义异常
         */
        @ExceptionHandler(MkException.class)
        public MkResponse handleHOPException(MkException e){
            MkResponse r = new MkResponse();
            r.put("returnCode", e.getReturnCode());
            r.put("returnMsg", e.getReturnMsg());
            r.put("errorCode", e.getErrorCode());
            r.put("errorMsg", e.getErrorMsg());
            logger.error(new Date() + ": " + e.getMessage(), e);
            return r;
        }
    
        @ExceptionHandler(NoHandlerFoundException.class)
        public MkResponse handlerNoFoundException(Exception e) {
            logger.error(new Date() + ": " + e.getMessage(), e);
            return MkResponse.error(NO_URL_FOUND, "路径不存在,请检查路径是否正确");
        }
    
        //大家可以自己定义其他的异常处理
    
        @ExceptionHandler(Exception.class)
        public MkResponse handleException(Exception e){
            logger.error(new Date() + ": " + e.getMessage(), e);
            return MkResponse.error(e.getMessage());
        }
    }
    

    统一的异常处理是不是挺简单,并且也将正常的业务逻辑处理和异常处理的代码分离开了,并且返回的错误报文格式都是统一的,是不是整个工程更加清晰了。在TestController中有个exception方法,大家可以调用试试效果。

    本文对应的github tag为v0.4,可以通过连接下载https://github.com/feiweiwei/MkFramework4java/releases/tag/v0.4,也可以通过git clone -b v0.4 https://github.com/feiweiwei/MkFramework4java.git

    相关文章

      网友评论

          本文标题:动手写个java快速开发框架-(4)统一异常处理

          本文链接:https://www.haomeiwen.com/subject/kfmugftx.html