Springboot全局异常统一处理

背景

以往的Java Web开发中,异常处理通常是通过try-catch语句块来实现。这种方法在应用程序规模较小的情况下还可以,但是在大型应用中,可能存在大量的代码重复和不一致问题。此外,在抛出未处理的异常时,用户会看到系统生成的默认错误页面,用户体验差。


全局异常统一处理

优点

  • 有助于保持代码整洁和规模化

    如果没有全局异常处理,每个Controller的方法都需要实现自己的异常处理,当程序变得越来越复杂时,这种代码会导致代码冗余和混乱的异常处理逻辑。

  • 提升用户体验

    全局异常处理允许应用程序捕获未处理的异常,并提供更友好的异常提示信息

  • 便于日志记录和监控

    全局异常处理可以帮助应用程序捕获和记录异常信息,在出现问题时快速定位。此外,还可以和监控系统继承,以实时跟踪应用程序中出现的异常情况。

  • 增强安全性

    全局异常处理可以防止应用程序出现潜在的安全漏洞,例如SQL注入和XSS攻击。


实操

1
2
3
4
5
<!--  web组件   -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

自定义一个异常类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GlobalException extends RuntimeException {
private RespBeanEnum respBeanEnum;

public RespBeanEnum getRespBeanEnum() {
return respBeanEnum;
}

public void setRespBeanEnum(RespBeanEnum respBeanEnum) {
this.respBeanEnum = respBeanEnum;
}
}

编写统一异常处理类,统一捕获处理返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestControllerAdvice // 表明统一处理异常
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class) // 希望捕获的异常类
public RespBean exceptionHandler(Exception e) {
if (e instanceof GlobalException) {
GlobalException ex = (GlobalException) e;
return RespBean.error(ex.getRespBeanEnum());
} else if (e instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
RespBean respBean = RespBean.error(RespBeanEnum.BIND_ERROR);
respBean.setMessage("参数校验异常:" + ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
return respBean;
}
return RespBean.error(RespBeanEnum.ERROR);
}
}