RestControllerAdvice 和 ControllerAdvice 两个注解的区别与联系

它们都用于实现全局的通用处理逻辑,主要应用在以下三个方面:

  1. 全局异常处理: 使用 @ExceptionHandler 注解的方法。
  2. 全局数据绑定: 使用 @InitBinder 注解的方法。
  3. 全局数据预处理: 使用 @ModelAttribute 注解的方法。

联系:

  1. 核心功能相同: 两者都提供了上述三种全局处理的能力。我们可以将原本分散在多个 Controller 中的通用异常处理、数据绑定规则、公共 Model 属性提取到标有这两个注解的类中统一管理。
  2. 都是 @Component: 从 Spring 的角度看,它们都是 @Component 的特殊化注解。这意味着 Spring 容器会自动扫描并注册这些 Bean。
  3. @RestControllerAdvice@ControllerAdvice 的组合注解: 这是最关键的联系。@RestControllerAdvice 本质上是 @ControllerAdvice@ResponseBody 两个注解的组合

查看 @RestControllerAdvice 的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice // <--- 包含了 @ControllerAdvice
@ResponseBody   // <--- 包含了 @ResponseBody
public @interface RestControllerAdvice {
   
   
    // ... 注解属性定义 ...
}

区别 (核心在于 @ResponseBody):

这个组合带来的核心区别在于对包含 @ExceptionHandler 注解的方法的返回值处理方式不同:

  1. @ControllerAdvice:

    • 如果其内部的 @ExceptionHandler 方法没有添加 @ResponseBody 注解,那么其返回值通常会被视图解析器(ViewResolver)处理。会返回一个 String 类型的视图名,或者一个 ModelAndView 对象,用于页面跳转或渲染。
    • 如果其内部的 @ExceptionHandler 方法添加了 @ResponseBody 注解,就和 @RestControllerAdvice 中的方法一样了,返回值会直接写入 HTTP 响应体中,通常是 JSON 或 XML 格式。
  2. @RestControllerAdvice:

    • 由于它自带了 @ResponseBody 注解,所以其内部所有 @ExceptionHandler 方法(以及 @ModelAttribute 方法)的返回值默认就会被 Spring MVC 当作响应体内容处理,通过 HttpMessageConverter 进行序列化(例如转为 JSON)并写入 Response Body。
    • 它特别适用于构建 RESTful API 的全局异常处理,因为 REST API 通常期望返回的是数据(如 JSON),而不是一个 HTML 视图。

总结与选择:

特性 @ControllerAdvice @RestControllerAdvice (@ControllerAdvice + @ResponseBody)
核心目的 全局 Controller 增强 (异常、数据绑定、模型属性) 全局 Controller 增强 (异常、数据绑定、模型属性)
基础注解 @Component @Component
组合 @ControllerAdvice + @ResponseBody
@ExceptionHandler 返回值默认处理 视图解析 (返回视图名/ModelAndView) 写入响应体 (通过 HttpMessageConverter 转为 JSON/XML 等)
适用场景 1. 传统的 Spring MVC 应用 (返回 HTML 视图)
2. 需要混合处理(部分返回视图,部分加 @ResponseBody 返回 JSON)的应用
3. 只用于全局 @InitBinder 或不返回数据的 @ModelAttribute
1. RESTful API (主要返回 JSON/XML 数据)
2. 所有全局异常都希望返回 JSON/XML 错误结构体

简单来说:

  • 如果你在构建一个传统的、主要返回 HTML 页面的 Spring MVC 应用,或者需要灵活处理部分返回视图、部分返回 JSON 的情况,使用 @ControllerAdvice。如果某个异常处理器需要返回 JSON,可以在该方法上单独加 @ResponseBody
  • 如果你在构建一个纯粹的 RESTful API,所有的 Controller 和异常处理都期望返回 JSON 或 XML 数据,那么使用 @RestControllerAdvice 更方便,因为它省去了在每个 @ExceptionHandler 方法上都写 @ResponseBody 的麻烦。

示例:

使用 @ControllerAdvice (可能返回视图)


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值