Spring Boot 异常处理

参考

一、全局异常处理

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
* Created with IntelliJ IDEA.
*
* @author Administrator
* Date: 2025/1/14
* Time: 12:37
* Description:全局异常处理类
*/
@RestControllerAdvice
public class GlobalRestExceptionHandler {

/**
* 处理异常
*
* @param ex 捕获异常类型
* @return 返回
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
return new ResponseEntity<>("网络服务错误", HttpStatus.INTERNAL_SERVER_ERROR);
}

/**
* 处理算数运算异常:如除零错误
*
* @param ex 捕获异常类型
* @return 返回
*/
@ExceptionHandler(ArithmeticException.class)
public ResponseEntity<String> arithmeticException(ArithmeticException ex) {
return new ResponseEntity<>("算数运行异常", HttpStatus.INTERNAL_SERVER_ERROR);
}

}

@RestControllerAdvice 相关设置

优先级设置:存在多个处理器时,使用@Order注解,设置处理器类优先级,例如@Order(Ordered.HIGHEST_PRECEDENCE)

范围设置: 存在多个处理器,例如全局处理器和多个局部处理器时,应当妥善设置范围,避免出现多个处理器同时处理同一个请求。

  • 指定包范围: basePackages: 指定一个或多个包,这些包及其子包下的所有 Controller 都被管理。
    • @RestControllerAdvice(“com.example.controller") // 只管理 com.example.controller 包及其子包下的所有 Controller
    • @RestControllerAdvice(basePackages={"com.example.controller","com.example.controller2"}) // 只管理 com.example.controller 包及其子包下的所有 Controller 和 com.example.controller2 包及其子包下的所有 Controller
    • 指定@RestControllerAdvice(basePackageClasses={Controller1.class,Controller2.class}) 是 basePackages 的一种变形,指定一个或多个 Controller 类,这些类所属的包及其子包下的所有 Controller 都被管理
  • 指定类: assignableTypes 指定一个或多个 Controller 类,这些类被管理
  • 指定注解: annotations 指定一个或多个注解,被这些注解所标记的 Controller 会被管理

处理404错误

即使我们配置了全局异常处理,当出现404 not found等4xx错误时,依然会出现意外情况:

1
2
3
4
5
6
7
8
9
10
11
{
"code": 200,
"msg": "ok",
"data": {
"timestamp": "2023-08-23T17:01:15.102+00:00",
"status": 404,
"error": "Not Found",
"path": "/test/nullapi"
},
"timestamp": 1692810075116
}

解决方法:
application.yml配置文件增加以下配置项:

1
2
3
4
5
6
7
8
9
# 当HTTP状态码为4xx时直接抛出异常
spring:
mvc:
# 高版本这个已经弃用
throw-exception-if-no-handler-found: true
# 关闭默认的静态资源路径映射
web:
resources:
add-mappings: false

现在当我们再次请求一个不存在的接口时,404的话控制台会报NoHandlerFoundException异常,然后被全局异常处理捕获到并统一返回。