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) |
看看结果:
