SpringMVC 中的 @ControllerAdvice
SpringMVC
中常用的注解网上有很多介绍,@ControllerAdvice
这个注解相对来说少见一点
从名称上就能看出, @ControllerAdvice
是用来增强 @Controller
的
使用 `@ControllerAdvice` 注解增强控制器
带有 `@ControllerAdvice` 注解的类,可以包含 @ExceptionHandler、@InitBinder, 和 `@ModelAttribute` 注解的方法,
并且这些注解的方法会通过控制器层次应用到所有 `@RequestMapping` 方法中,而不用一一在控制器内部声明。
看到上面这段话,大家有没有一种兴奋感?
在没有 @ControllerAdvice
之前, 我们是怎么使用 @ExceptionHandler
的呢? 很简单,我们给 Controller
定义父类,在父类中又一个方法,被 @ExceptionHandler
修饰的方法,
在这里处理, 从上面这句话来说,我们现在并不需要定义什么父类,只要用 @ControllerAdvice
修饰一个类,它就能成为全局异常处理器!
Talk is cheap, show me the code!
先来一个 Controller:
1 |
|
再来一个 ControllerAdvice, 直接返回一个 json 格式的异常信息
1 |
|
再来贴一下 spring 配置信息:
1 | <?xml version="1.0" encoding="UTF-8"?> |
看看运行结果,很不错,我们实现了全剧异常处理
到这里大家会比较疑惑,为什么 ControllerAdvice 可以被自动扫描呢?
先来看看源码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 (ElementType.TYPE)
(RetentionPolicy.RUNTIME)
public ControllerAdvice {
"basePackages") (
String[] value() default {};
"value") (
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] assignableTypes() default {};
Class<? extends Annotation>[] annotations() default {};
}
我们可以看到 @ControllerAdvice
是一个 @Component
, 它当然能被扫描
除了 @ExceptionHandler
之外,还有 @InitBinder
、@ModelAttribute
修饰的方法,不是很常用
这里如果只是 这三个功能, @ControllerAdvice
还略显鸡肋
下面来看看 Spring 4.2
以来的新特性 ResponseBodyAdvice
和 RequestBodyAdvice
ResponseBodyAdvice
的源码:
1 | public interface ResponseBodyAdvice<T> { |
我们可以看到这里, 我们可以对 @ResponseBody
修饰的方法的返回值进行处理
比如我们对返回结果进行国际化处理,
来个简单的例子:
1 | (annotations = RestController.class) |
看看结果: