springboot springmvc 全局异常处理

    技术2023-09-24  78

    主要利用 spring-webmvc提供的@ControllerAdvice注解和@ExceptionHandler注解,所以springwebmvc的依赖必不可少。 @ControllerAdvice作用在类上,表明使用该类对controller中抛出的异常进行捕获处理。 @ExceptionHandler作用在方法上,需要指定异常的字节码数组,以便说明该方法是用来处理哪些异常。 下面我们按步骤演示一个完整的异常处理。 注:下面的代码为了方便使用了lombok。

    1. 定义ExceptionResult类(VO),因为项目是前后端分离,出现异常后,我们需要将一些必要的异常信息返回给前端展示。一般定义一个状态码,异常的提示信息,时间戳等等,这些字段根据自己的需要添加。
    @Data public class ExceptionResult { private int status; private String message; private Long timestamp; // ExceptionEnums是一个枚举类,管理我们项目中自定义的异常信息和状态码 public ExceptionResult(ExceptionEnums exceptionEnums) { this.status = exceptionEnums.getCode(); this.message = exceptionEnums.getMsg(); this.timestamp = System.currentTimeMillis(); } }

    2. 自定义ExceptionEnums枚举类,管理我们项目中自定义的异常信息和状态码。

    @Getter @AllArgsConstructor public enum ExceptionEnums { USERNAME_CANNOT_BE_NULL(400,"用户名不能为空"), PASSWORD_CANNOT_BE_NULL(401,"密码不能为空"); private final int code; private final String msg; }

    3. 自定义CustomException异常类,有了该异常类,我们就可以在全局异常处理器中捕获他,进行处理。该异常类需要继承RuntimeException而不是Exception。因而该自定义异常可以直接抛出,而不用在controller方法上声明。

    @Getter @AllArgsConstructor public class LyException extends RuntimeException{ // 在抛该异常实例化的时候需要传入我们的枚举类对象,这样做的目的是携带我们自定义的异常信息和状态码 private ExceptionEnums exceptionEnums; }

    4. 创建全局异常处理器,捕获我们第三步自定义的异常,实现通用的异常处理。

    @ControllerAdvice public class CommonExceptionHandler { @ExceptionHandler(CustomException.class) public ResponseEntity<ExceptionResult> handleException(CustomException customException) { // 获取存储自定义异常信息和状态码的枚举对象 ExceptionEnums exceptionEnums = customException.getExceptionEnums(); return ResponseEntity.status(exceptionEnums.getCode()).body(new ExceptionResult(exceptionEnums)); } }

    关于ResponseEntity<T>,使用这个类我们可以设置响应行的status,同时可以序列化不同类型的数据到响应体中。

    5. 在controller方法中需要的地方抛出异常。如果Service层出现需要捕获的异常,需要抛到controller。

    @Controller("user") public class UserController { @Autowired private UserService userService; @RequestMapping("login") public ResponseEntity<Item> login(User user) { if (StringUtils.isBlank(user.getUsername)) { throw new CustomException(ExceptionEnums.USERNAME_CANNOT_BE_NULL); } user = userService.login(user); return ResponseEntity.ok(user); } }

    6.测试我们的接口,不传username,看一下效果。

    Processed: 0.014, SQL: 9