@RestControllerAdvice 的作用
系列博客目录
文章目录
- 系列博客目录
- 1.@ControllerAdvice 有什么用
- 主要功能
- 2.与 `@RestControllerAdvice` 的区别
- 3.苍穹外卖中的使用
- 4.@RestControllerAdvice可以指定范围吗
- (1)指定应用到某些包中的 `@RestController`
- (2)指定应用到具有特定注解的 `@RestController`
- (3)指定应用到特定的 `@RestController` 类
- (4)组合使用多个限制条件
- 小结
- 总结
1.@ControllerAdvice 有什么用
@ControllerAdvice
是 Spring 框架提供的一个用于处理全局异常、数据绑定、模型属性等的注解。它可以用来集中处理应用中的异常、日志记录、数据预处理等常见任务,从而减少重复的代码,提高可维护性。
主要功能
-
全局异常处理
@ControllerAdvice
允许你在一个集中位置处理控制器(@Controller
)抛出的异常。这样,你就不需要在每个控制器方法中写重复的异常处理代码。@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception ex) { return new ResponseEntity<>("Global exception: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } }
上面的代码会捕获所有控制器抛出的
Exception
异常,并返回统一的响应。 -
全局数据绑定
@ControllerAdvice
还可以用于设置全局的模型属性,比如向所有的视图中添加一些通用数据(如当前用户信息等)。@ControllerAdvice public class GlobalModelAttributes { @ModelAttribute("user") public User addUser() { return new User("John", "Doe"); } }
这里,
user
将会自动成为所有视图模型中的一个属性。 -
全局
@InitBinder
@InitBinder
方法可以用于设置 Web 层的数据绑定配置。通过@ControllerAdvice
可以设置全局的数据绑定方法,比如日期格式、字符串的修剪等。@ControllerAdvice public class GlobalBinderConfig { @InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); } }
通过
@InitBinder
,你可以为所有的控制器设置全局的数据绑定规则。 -
局部作用域
如果你不希望@ControllerAdvice
处理全局的异常,也可以通过@RestControllerAdvice
或者指定basePackages
限制@ControllerAdvice
的作用范围,使其仅对指定的包或类有效。
2.与 @RestControllerAdvice
的区别
@ControllerAdvice
用于传统的基于视图的控制器(即返回视图页面的控制器)。@RestControllerAdvice
是专门为@RestController
设计的,通常用于处理返回 JSON 或 XML 的 RESTful API,它是@ControllerAdvice
和@ResponseBody
的组合。
3.苍穹外卖中的使用
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 捕获业务异常
* @param ex
* @return
*/
@ExceptionHandler
public Result exceptionHandler(BaseException ex){
log.error("异常信息:{}", ex.getMessage());
return Result.error(ex.getMessage());
}
}
4.@RestControllerAdvice可以指定范围吗
是的,@RestControllerAdvice
也可以指定范围,类似于 @ControllerAdvice
。你可以通过以下几种方式来限制 @RestControllerAdvice
的作用范围:
(1)指定应用到某些包中的 @RestController
使用 basePackages
属性,你可以限制 @RestControllerAdvice
只作用于某些包中的 @RestController
类。
@RestControllerAdvice(basePackages = "com.example.demo.rest")
public class RestControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
return new ResponseEntity<>("REST exception: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
在这个例子中,@RestControllerAdvice
只会作用于 com.example.demo.rest
包中的 @RestController
控制器。
(2)指定应用到具有特定注解的 @RestController
你可以使用 annotations
属性,限制 @RestControllerAdvice
只作用于具有特定注解的控制器。例如,@RestController
或其他自定义注解。
@RestControllerAdvice(annotations = RestController.class)
public class RestControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleRestControllerException(Exception ex) {
return new ResponseEntity<>("REST controller exception: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
这意味着 @RestControllerAdvice
只会影响被 @RestController
注解标记的控制器类。
(3)指定应用到特定的 @RestController
类
你还可以通过 assignableTypes
属性来限制 @RestControllerAdvice
只作用于某些指定类型的控制器类。
@RestControllerAdvice(assignableTypes = MyRestController.class)
public class SpecificRestControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleSpecificRestControllerException(Exception ex) {
return new ResponseEntity<>("Exception in MyRestController: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
在这个例子中,@RestControllerAdvice
只会作用于 MyRestController
类中的 @RestController
。
(4)组合使用多个限制条件
你还可以结合多种属性来进一步细化 @RestControllerAdvice
的应用范围,例如同时指定 basePackages
和 annotations
:
@RestControllerAdvice(basePackages = "com.example.demo.rest", annotations = RestController.class)
public class RestControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleRestControllerException(Exception ex) {
return new ResponseEntity<>("REST API exception: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
小结
@RestControllerAdvice
提供了类似于 @ControllerAdvice
的功能,可以通过 basePackages
、annotations
和 assignableTypes
等属性来精确控制其适用范围。这样,你就可以将它限制在特定的包、注解或控制器类中,从而避免不必要的影响,增强代码的可维护性和清晰性。
总结
@ControllerAdvice
是 Spring 中一种集中处理异常、模型属性、数据绑定等的机制,它让你可以在一个地方集中管理所有控制器相关的操作,从而使得代码更加简洁和可维护。