@ControllerAdvice
@ControllerAdvice 是 Spring MVC 中的一个全局增强组件。
它的作用可以理解为:
给所有 @Controller 或
@RestController 统一增加公共能力。
最常见的用途:
1. 全局异常处理
2. 全局数据绑定
3. 全局参数预处理
4. 全局返回值封装
面试中经常问:
Spring Boot 如何实现统一异常处理?
答案基本就是:
@ControllerAdvice
+ @ExceptionHandler
一、没有@ControllerAdvice的问题
假设有一个查询用户接口
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
int i = 1 / 0;
return "success";
}
}
访问:
GET /user/1
结果:
{
"timestamp":"2025-06-03",
"status":500,
"error":"Internal Server Error"
}
返回一大堆 Spring 默认异常信息。
如果项目有:
100个Controller
1000个接口
每个接口都写:
try{
...
}catch(Exception e){
...
}
会非常恶心。
二、@ControllerAdvice出现
创建:
@ControllerAdvice
public class GlobalExceptionHandler {
}
它会被 Spring 扫描。
然后监听异常:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public String handler(Exception e){
return "系统异常:" + e.getMessage();
}
}
三、执行流程
请求:
GET /user/1
Controller:
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
int i = 1 / 0;
return "success";
}
异常:
ArithmeticException
Spring发现:
@ControllerAdvice
里面有:
@ExceptionHandler(Exception.class)
匹配成功。
执行:
handler()
返回:
系统异常:/ by zero
四、企业级写法
统一返回结构:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {
private Integer code;
private String msg;
private T data;
}
异常处理:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Result<String> handler(Exception e){
return new Result<>(
500,
e.getMessage(),
null
);
}
}
注意:
@RestControllerAdvice
=
@ControllerAdvice
+
@ResponseBody
实际项目几乎都用:
@RestControllerAdvice
五、自定义异常
例如用户不存在。
定义异常:
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String msg){
super(msg);
}
}
业务代码:
@GetMapping("/{id}")
public String getUser(@PathVariable Long id){
if(id == 0){
throw new UserNotFoundException("用户不存在");
}
return "张三";
}
处理指定异常:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public Result<String> userException(
UserNotFoundException e){
return new Result<>(
404,
e.getMessage(),
null
);
}
}
结果:
{
"code":404,
"msg":"用户不存在",
"data":null
}
六、多个异常处理方法
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public Result<?> userException(
UserNotFoundException e){
return Result.fail(e.getMessage());
}
@ExceptionHandler(SQLException.class)
public Result<?> sqlException(
SQLException e){
return Result.fail("数据库异常");
}
@ExceptionHandler(Exception.class)
public Result<?> exception(
Exception e){
return Result.fail("系统异常");
}
}
匹配规则:
先找具体异常
再找父异常
最后Exception
例如:
NullPointerException
会走:
Exception.class
七、参数校验异常统一处理
Controller:
@PostMapping("/save")
public String save(
@Valid @RequestBody UserDTO dto){
return "success";
}
DTO:
@Data
public class UserDTO {
@NotBlank
private String name;
}
用户传:
{
}
抛出:
MethodArgumentNotValidException
统一处理:
@ExceptionHandler(
MethodArgumentNotValidException.class)
public Result<?> validException(
MethodArgumentNotValidException e){
String msg =
e.getBindingResult()
.getFieldError()
.getDefaultMessage();
return Result.fail(msg);
}
返回:
{
"code":400,
"msg":"name不能为空"
}
八、@InitBinder
除了异常处理,
@ControllerAdvice 还能做全局参数绑定。
例如日期格式转换:
@ControllerAdvice
public class GlobalBinding {
@InitBinder
public void initBinder(WebDataBinder binder){
SimpleDateFormat sdf =
new SimpleDateFormat(
"yyyy-MM-dd");
binder.registerCustomEditor(
Date.class,
new CustomDateEditor(
sdf,
true
)
);
}
}
Controller:
@GetMapping("/test")
public String test(Date createTime){
return "success";
}
请求:
/test?createTime=2026-06-04
自动转换:
Date
九、@ModelAttribute
全局添加公共数据。
@ControllerAdvice
public class GlobalModel {
@ModelAttribute
public void addAttr(Model model){
model.addAttribute(
"version",
"1.0"
);
}
}
所有 Controller 都能拿到:
model.getAttribute("version");
十、标准答案
问:
@ControllerAdvice有什么作用?
回答:
@ControllerAdvice 是 Spring MVC 提供的全局增强组件,可以对所有 Controller 进行统一处理。最常用于全局异常处理(配合 @ExceptionHandler)、全局参数绑定(@InitBinder)以及全局模型数据设置(@ModelAttribute)。在 Spring Boot 项目中通常使用 @RestControllerAdvice 实现统一异常返回,避免在每个接口中编写重复的 try-catch 代码。
企业项目里最常见的代码组合是:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result<?> businessException(
BusinessException e){
return Result.fail(e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result<?> exception(
Exception e){
return Result.fail("系统繁忙,请稍后重试");
}
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)