spring中@ControllerAdvice 注解的使用
作者:快乐的小三菊
一、简介
@ControllerAdvice 注解是 spring3.2 中新增的注解,学名是 Controller 增强器,主要是为了给 Controller 控制器添加统一的操作或处理。
@ControllerAdvice 注解是在类上面声明的注解。
二、作用
1、搭配 @ExceptionHandler 一起使用,可以做到全局异常处理。
2、搭配 @ModelAttribute 一起使用,可以做到添加全局数据,在方法执行前进行一些操作。
3、搭配 @InitBinder 一起使用,可以做到请求参数预处理,即绑定一些自定义参数。
三、搭配 @ExceptionHandler 使用
我们可以使用 @ExceptionHandler 捕获 RuntimeException 异常,代码如下:
@ControllerAdvice public class SpringControllerAdvice { @ExceptionHandler(RuntimeException.class) public ModelAndView runtimeExceptionHandler(RuntimeException e) { e.printStackTrace(); return new ModelAndView("error"); } }
我们还可以使用 @ExceptionHandler 捕获自定义异常,代码如下:
public class CustomException extends RuntimeException { private AppHttpCodeEnum appHttpCodeEnum; public CustomException(AppHttpCodeEnum appHttpCodeEnum){ this.appHttpCodeEnum = appHttpCodeEnum; } public AppHttpCodeEnum getAppHttpCodeEnum() { return appHttpCodeEnum; } }
@ControllerAdvice @Slf4j public class ExceptionCatch { @ExceptionHandler(CustomException.class) @ResponseBody public ResponseResult exception(CustomException e){ log.error("catch exception:{}",e); return ResponseResult.errorResult(e.getAppHttpCodeEnum()); } }
我们还可以使用 @ExceptionHandler 捕获不可控的全局异常,代码如下:
@ControllerAdvice @Slf4j public class ExceptionCatch { @ExceptionHandler(Exception.class) @ResponseBody public ResponseResult exception(Exception e){ e.printStackTrace(); log.error("catch exception:{}",e.getMessage()); return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR); } }
调用下面的测试方法,代码如下,当访问 /users 的时候,因为在该方法中抛出了 RuntimeException,这里的异常捕获器就会捕获该异常,然后返回我们定义的异常视图(默认的error 视图)。
@Controller public class UserController { @RequestMapping(value = "/users", method = RequestMethod.GET) public void users() { throw new RuntimeException("没有任何用户。"); } }
四、搭配 @InitBinder 使用
对于 @InitBinder,该注解的主要作用是绑定一些自定义的参数。如下代码:
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface InitBinder { // 这里value参数用于指定需要绑定的参数名称,如果不指定,则会对所有的参数进行适配, // 只有是其指定的类型的参数才会被转换 String[] value() default {}; }
一般情况下我们使用的参数通过 @RequestParam,@RequestBody 或者 @ModelAttribute等注解就可以进行绑定了。但对于一些特殊类型参数,比如 Date,它们的绑定 Spring 是没有提供直接的支持的。我们只能为其声明一个转换器,将 request 中字符串类型的参数通过转换器转换为 Date 类型的参数,从而供给 @RequestMapping 标注的方法使用。
如下代码,使用 @InitBinder 注册 Date 类型参数转换器的实现:
@ControllerAdvice public class SpringControllerAdvice { @InitBinder public void globalInitBinder(WebDataBinder binder) { binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd")); } }
这里 @InitBinder 标注的方法注册的 Formatter 在每次 request 请求进行参数转换时都会调用,用于判断指定的参数是否为其可以转换的参数。可以看到当访问 /users 的时候,对 request 参数进行了转换,并且在接口方法中成功接收了该参数,并在控制台打印出日期格式的结果。
五、搭配 @ModelAttribute 使用
关于 @ModelAttribute 的用法,除了用于方法参数时可以用于转换对象类型的属性之外,其还可以用来进行方法的声明。如果声明在方法上,并且结合 @ControllerAdvice,该方法将会在 @ControllerAdvice 所指定的范围内的所有接口方法执行之前执行,并且 @ModelAttribute 标注的方法的返回值还可以供给后续会调用的接口方法使用。
该注解的定义方法如下所示:
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ModelAttribute { // 该属性与name属性的作用一致,用于指定目标参数的名称 @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; // 与name属性一起使用,如果指定了binding为false,那么name属性指定名称的属性将不会被处理 boolean binding() default true; }
这里 @ModelAttribute 的各个属性值主要是用于其在接口方法参数上进行标注时使用的,如果是作为方法注解,其 name 或 value 属性则指定的是返回值的名称。如下面的例子:
@ControllerAdvice public class SpringControllerAdvice { @ModelAttribute(value = "message") public String globalModelAttribute() { System.out.println("添加了message全局属性。"); return "输出了message全局属性。"; } }
测试代码如下:
@Controller public class UserController { @RequestMapping(value = "/users", method = RequestMethod.GET) public void users(@ModelAttribute("message") String message) { System.out.println(message); } }
这里 @ModelAttribute 注解的方法提供了一个 String 类型的返回值,而 @ModelAttribute 注解中指定了该属性的名称是 message,这样在 Controller 层就可以通过 @ModelAttribute 注解接收名称为 message 的参数,从而获取到前面绑定的参数了。
需要说明的是,@ModelAttribute 标注的方法的执行是在所有的拦截器的 preHandle() 方法执行之后才会执行。
参考博客地址:https://www.cnblogs.com/hdfu/p/17699137.html
到此这篇关于spring中@ControllerAdvice 注解的使用的文章就介绍到这了,更多相关spring @ControllerAdvice 注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!