news 2026/6/5 10:09:04

@ControllerAdvice

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
@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("系统繁忙,请稍后重试"); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 10:06:58

Copilot时代的程序员:这5个能力比写代码更重要

Copilot时代的程序员&#xff1a;这5个能力比写代码更重要凌晨两点&#xff0c;你盯着屏幕上AI生成的一段"看似正确但运行就报错"的代码&#xff0c;陷入了沉思。 这不是段子。这是过去一年里&#xff0c;无数程序员真实的工作状态。 当GitHub Copilot成为默认的编程…

作者头像 李华
网站建设 2026/6/5 10:05:01

上班族 AI 学习方案 第六周RAG 私有知识库(职场刚需 TOP1)

欢迎来到第 6 周&#xff01;这周我们要攻克的是当前企业级 AI 应用中最核心、最刚需的技术——RAG&#xff08;检索增强生成&#xff09;私有知识库。如果说通用大模型是一个“无所不知但不懂你公司业务的实习生”&#xff0c;那么 RAG 就是给这个实习生配了一本“公司内部专属…

作者头像 李华
网站建设 2026/6/5 10:02:23

从收音机到手机:高频谐振放大器电路设计中的那些“坑”与避雷指南

从收音机到手机&#xff1a;高频谐振放大器电路设计中的那些“坑”与避雷指南在无线通信技术从模拟收音机演进到5G手机的历程中&#xff0c;高频谐振放大器始终扮演着关键角色。这种能够同时实现信号放大和频率选择的电路&#xff0c;既出现在老式收音机的中频放大级&#xff0…

作者头像 李华