您的位置:首页 > 编程语言 > Java开发

SpringBoot 之全局异常处理

2019-07-29 11:31 561 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/cc_joke/article/details/97630250
  • 前言:service方法在执行过程出现异常在哪捕获?在service中需要都加try/catch,如果在controller也需要添加 try/catch,代码冗余严重且不易维护。 这时候需要在统一异常处理类中去捕获异常,无需controller捕获异常,向用户返回统一规范的响应信息。

  • 异常分两种:可预知的异常(业务判断等)由程序员在代码中主动抛出自定义异常,由SpringMVC统一捕获。

    不可预知的异常(系统bug等)由SpringMVC统一捕获Exception类型的异常。

    一、可预知的异常处理

    1.1 统一返回给前端的结果

    public interface ResultCode {
       //操作是否成功,true为成功,false操作失败
       boolean success();
       //操作代码
       int code();
       //提示信息
       String message();
    }

    1.2 定义错误代码

    @ToString
    public enum CommonCode implements ResultCode{
       SUCCESS(true,10000,"操作成功!"),
       FAIL(false,11111,"操作失败!"),
       CUSTOM(false,10003,"测试自定义异常!"),
    ​
       //操作是否成功
       boolean success;
       //操作代码
       int code;
       //提示信息
       String message;
       private CommonCode(boolean success,int code, String message){
           this.success = success;
           this.code = code;
           this.message = message;
       }
    ​
       @Override
       public boolean success() {
           return success;
       }
       @Override
       public int code() {
           return code;
       }
    ​
       @Override
       public String message() {
           return message;
       }
       
    }

    1.3在common工程定义异常类型。

    (实现RuntimeException是因为secrice有异常时不需要throws异常)

    /**
    * 自定义异常类型
    **/
    public class CustomException extends RuntimeException {
       //错误代码
       ResultCode resultCode;
    ​
       public CustomException(ResultCode resultCode){
           this.resultCode = resultCode;
       }
       public ResultCode getResultCode(){
           return resultCode;
       }
    }
    ​

    1.4 异常抛出类

    public class ExceptionCast {
       //使用此静态方法抛出自定义异常
       public static void cast(ResultCode resultCode){
           throw new CustomException(resultCode);
       }
    }
    ​

    1.5 异常捕获类

    使用 @ControllerAdvice和@ExceptionHandler注解来捕获指定类型的异常

    /**
    * 统一异常捕获类
    **/
    @ControllerAdvice   //控制器增强
    public class ExceptionCatch {
    ​
       private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
       //捕获CustomException此类异常
       @ExceptionHandler(CustomException.class)
       @ResponseBody
       public ResponseResult customException(CustomException customException){
           customException.printStackTrace();
           //记录日志
           LOGGER.error("catch exception:{}",customException.getMessage());
           ResultCode resultCode = customException.getResultCode();
           return new ResponseResult(resultCode);
       }
       
    }

    1.6 测试异常(在controller、service、 dao中都可以抛出异常。 )

    1.6.1 手动抛异常

    int a=1;
    if(a ==1){  //如果a等于1时
       ExceptionCast.cast(CommonCode.CUSTOM); //手动抛出自定义异常
    }

    1.6.2启动工程,扫描到异常捕获的类ExceptionCatch

    在springBoot的启动类中添加

   @ComponentScan(basePackages="com.framework")//扫描common工程下的异常类

二、不可预知异常处理 (用空指针异常测试)

1.在通用错误代码类CommCode中配置空指针异常

NULL_POINTER(false,10003,"控制针异常!"),
SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!");

2.在异常捕获类(ExceptionCatch)中添加对Exception异常的捕获:

  //捕获Exception此类异常
   @ExceptionHandler(Exception.class)
   @ResponseBody
   public ResponseResult exception(Exception exception){
      exception.printStackTrace();
       //记录日志
       LOGGER.error("catch exception:{}",exception.getMessage());
       if(EXCEPTIONS == null){
           EXCEPTIONS = builder.build();//EXCEPTIONS构建成功
       }
       //从EXCEPTIONS中找异常类型所对应的错误代码,如果找到了将错误代码响应给用户,如果找不到给用户响应99999异常
       ResultCode resultCode = EXCEPTIONS.get(exception.getClass());
       if(resultCode !=null){
           return new ResponseResult(resultCode);
       }else{
           //返回99999异常
           return new ResponseResult(CommonCode.SERVER_ERROR);
       }
​
​
   }
   static {
       //定义异常类型所对应的错误代码
       builder.put(NullPointerException.class,CommonCode.NULL_POINTER);
   }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: