SpringBoot 全局异常处理类

SpringBoot 全局异常处理类

  1. 定义一个自己的全局错误处理类继承RuntimeException,类名自定义,我的全局错误处理类名字是NingException。如下面代码。
    (继承Exception或Throwable会报错,原因在文章最后)
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class NingException extends RuntimeException {
    int code;//错误码
    String massage;//错误提示信息

	//含参构造,用于接收数据
    public NingException(int code, String massage) {
        this.code = code;
        this.massage = massage;
    }
}
  1. 创建一个ExceptionHandler类,主要是用@ControllerAdvice和 @ExceptionHandler处理错误信息,同样名字可以自定义,我创建的叫NingExceptionHandler,代码如下。 其中
    @ExceptionHandler(value = XXXXXX.class)或
    @ExceptionHandler(XXXXXX.class)中的XXXXXX是自定义的全局错误处理类名。 按我的代码就是
    @ExceptionHandler(value = NingException.class)
@ControllerAdvice
public class NingExceptionHandler {
	//表示这个方法处理的就是 NingException中的错误信息
    @ExceptionHandler(value = NingException.class)
    @ResponseBody
    public Map ningError(NingException e){
        e.printStackTrace();
        //将错误信息封装到map中并返回,也可以用其他方法,宗旨是返回给前端错误信息
        Map<String , Object> map = new HashMap<>();
        map.put("code",e.getCode());
        map.put("massage",e.getMassage());
        return map;
    }
}
  1. 完成上面两步,你就可以进行测试和使用了! 在controller中自定义了一个错误,用于测试:
@RequestMapping(value = "/back/user")
@Controller
public class BackUserController {

    @RequestMapping(value = "/addBackUser")
    public void addBackUser(){
        try {
            int a = 10/0;
        }catch (Exception e ){
        //此处定义错误码为202,错误提示为"测试报错"
           throw new NingException(202,"测试报错");
        }
    }
    
}
  1. 这是测试结果 测试成功

SpringBoot 全局异常处理类_第1张图片

  1. 这样基本的异常处理就完成了,后来考虑到会有很多常用的报错信息,为了降低代码的重复和方便将来批量修改,在原有基础上可以通过枚举实现一些常用错误的封装!
  1. 新建一个enum(枚举) 用来封装常用的错误信息,枚举类名自定义。 我的枚举叫NingExceptionEnum,代码如下。
public enum NingExceptionEnum {

    userE(202,"用户错误"),
    selectE(201,"查询报错");
	//错误码
    private Integer code;
    //错误提示
    private String massage;
    NingExceptionEnum(Integer code,String massage) {
        this.code = code;
        this.massage = massage;
    }

    public Integer getCode() {
        return code;
    }

    public String getMassage() {
        return massage;
    }
}

  1. 在之前创建的错误处理类(NingException)中再加入个含参构造,用来接收枚举的信息
@Data
@NoArgsConstructor
public class NingException extends RuntimeException {
   int code;
   String massage;

   public NingException(int code, String massage) {
       this.code = code;
       this.massage = massage;
   }
   //接收通过枚举传来的错误数据
   public NingException(NingExceptionEnum ningExceptionEnum) {
   	   //错误码
       this.code = ningExceptionEnum.getCode();
        //错误提示
       this.massage = ningExceptionEnum.getMassage();
   }
}

  1. 修改测试controller的报错参数为枚举中的定义的变量 例如 抛出枚举中的selectE错误
@RequestMapping(value = "/back/user")
@Controller
public class BackUserController {


    @RequestMapping(value = "/addBackUser")
    public void addBackUser(){
        try {
            int a = 10/0;
        }catch (Exception e ){
        	//抛出枚举中的selectE错误
            throw new NingException(NingExceptionEnum.selectE);
        }
    }

}

  1. 测试一下,成功抛出异常

SpringBoot 全局异常处理类_第2张图片

  1. 总结:一般实际生产中使用异常处理类, 对于前端而言在对接中会省事一些,所有的异常信息返回的数据结构相同,前端处理错误的代码就可以复用!
    对于后端而言,一些不重复使用的错误要自己写错误提示,重复的错误可以通过枚举实现。这样既灵活也可为以后代码批量变动时做好准备!
    所以自己定义一个异常处理类可以使工作更加自然和丝滑!
  1. 关于使用Exception和Throwable会报错的问题

最开始定义全局异常处理类时,我想的是直接继承Exception,这样就可以扑捉更多异常,后来测试时,一直报错,所以就特殊的看了看这个点,关于错误的区分:

1、非RuntimeException: 非运行时异常,在项目运行之前必须处理掉。一般由程序员try catch 掉。
2、RuntimeException,运行时异常,在项目运行之后出错则直接中止运行,异常由JVM虚拟机处理。

可以看出当程序运行时的异常抛出都应该由RuntimeException处理,而非Exception和Throwable;
还有一个最直接的理由,就是不继承RuntimeException,代码报错!

  1. 还有一篇文章是通过切面实现的 try catch错误处理,和此篇文章相辅相成。
    文章转跳SpringBoot 自定义切面完成异常处理实现代码优化

你可能感兴趣的:(springboot技术类,java,spring,架构,bug)