异常的统一处理

异常处理

简单说说

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

  • 自定义异常类型

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

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

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

完!

posted @ 2019-06-26 23:40  鞋破露脚尖儿  阅读(246)  评论(0编辑  收藏  举报