• 异常的统一处理


    异常处理

    简单说说

    为了避免代码冗余以及异常信息不明确,我们一般都是使用自定义异常,然后在统一异常处理类中捕获并处理,处理完后封装到统一的响应中返回给客户端

    • 自定义异常类型

    • 自定义错误代码以及错误信息

    • 可预知异常在代码中手动抛出,由SpringMVC控制器增强统一捕获

    • 不可知异常由SpringMVC统一捕获Exception处理

    • 无论可预知还是不可知异常,最后都采用统一的信息格式响应给客户端

    可预知异常处理

    自定义异常类

      

    • ResultCode:封装了三个信息,分别是: 是否成功、响应码、提示信息

    • 提供get(),至于set()是通过构造方法传入并赋值

    异常抛出类

       

    • 这个就是我们再代码中想抛出预知异常所使用的类

    • 通过静态方法cast(),传入异常的具体信息,然后抛出一个自定义异常,将异常信息作为参数带入

    异常捕获类

      

    • @ControllerAdvice:统一异常处理

    • @RestControllerAdvice:如果统一响应的Json数据,可以使用这个

    • @ExceptionHandle:有一个方法指定捕获的异常类型,捕获后交由下方函数处理

    统一响应格式

      

    小测试

    if ( ){
        //对什么进行判断,并抛出自定义异常
        ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTSNAME);
     }

    至于:CmsCode.CMS_ADDPAGE_EXISTSNAME

    是一个枚举类,固定了: 是否成功--响应码--提示信息

    不可预知异常

    简单说说:所谓的不可预知异常,一般指的是请求数据转换异常,数据库连接异常...等

    异常捕获方法

      因为太长,我就贴代码了:

      
     //使用ImmutableMap存放异常类型和错误代码的映射,这个对象线程安全,一旦创建不可变
        private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTION_MAP;
        //使用builder来构建一个异常类型和错误代码的异常
        protected  static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder();
       
        @ExceptionHandler(Exception.class)
        @ResponseBody
        public ResponseResult Exception(Exception e){
            LOGGER.error("catch Exception:",e.getMessage(),e);
            //如果集合为空
            if (EXCEPTION_MAP == null)
                //构建集合
                EXCEPTION_MAP = builder.build();
                //尝试在集合中或许捕获的异常信息
                final ResultCode resultCode = EXCEPTION_MAP.get(e.getClass());
                //定义统一的响应体
                final ResponseResult response;
                //如果集合中有这个异常相关的信息
                if (resultCode != null){
                    //将异常信息封装到统一响应体中返回,我们只有一个数据,那就是: false---10003---非法参数
                    response = new ResponseResult(resultCode);
                }else{
                    //CommonCode.SERVER_ERROR:false - 99999 - 系统繁忙,请稍后再试
                    response = new ResponseResult(CommonCode.SERVER_ERROR);
                }
                return response;
        }
     //我们手动加入一部风数据到map中,待会儿用于测试
        static{
            //接口要就post提交时,我们不给Json数据直接提交,以add为列,触发这个异常然后被捕获
          //CommonCode.INVALID_PARAM :false --- 10003-----非法参数
            builder.put(HttpMessageNotReadableException.class, CommonCode.INVALID_PARAM);
        }

    稍作解释:

    • 我们定义了一个Map() :

      • key是一个异常,因为泛型规定了他必须继承Throwable

      • Value是触发该异常后的响应信息(是否操作成功----响应码----提示信息)

         <dependency>
               <groupId>com.google.guava</groupId>
               <artifactId>guava</artifactId>
         </dependency>
      • 当我们拦截到未预知的异常时,首先去这个集合中查询室友有相关的信息

      • 如果有,就直接封装对应的Value到统一响应体中响应

      • 如果在集合中没有查询到对应的异常信息,统一返回:"系统繁忙"这个响应体

    完!

  • 相关阅读:
    zbb20180929 dubbo+zookeeper
    zbb20180929 Linux高可用之Keepalived
    zbb20180929 zk Zookeeper的功能以及工作原理
    zbb20180927 Union与Union All的区别
    zbb20180927 MySQL MyISAM InnoDB区别
    zbb20180921 spring事物的七种事物传播属性行为及五种隔离级别
    zbb20180921 java,md5,MD5加密+加盐
    zbb20180921 java,js,javascript 前端加密后端解密Base64通用加密处理
    zbb20180921 springboot 全局异常处理 404 500
    zbb20180919 db,mysql MySQL慢查询
  • 原文地址:https://www.cnblogs.com/msi-chen/p/11094581.html
Copyright © 2020-2023  润新知