• 异常的统一处理


    异常处理

    简单说说

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

    • 自定义异常类型

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

    • 可预知异常在代码中手动抛出,由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到统一响应体中响应

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

    完!

  • 相关阅读:
    bzoj 4012: [HNOI2015]开店
    POJ 1054 The Troublesome Frog
    POJ 3171 Cleaning Shifts
    POJ 3411 Paid Roads
    POJ 3045 Cow Acrobats
    POJ 1742 Coins
    POJ 3181 Dollar Dayz
    POJ 3040 Allowance
    POJ 3666 Making the Grade
    洛谷 P3657 [USACO17FEB]Why Did the Cow Cross the Road II P
  • 原文地址:https://www.cnblogs.com/msi-chen/p/11094581.html
Copyright © 2020-2023  润新知