在Spring3.2中,新增了@ControllerAdvice注解。关于这个注解的官方说明https://docs.spring.io/spring-framework/docs/5.0.0.M1/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html

我们可以根据字面意思将这个注解理解为Controller的Advice(在spring aop中,Advice被翻译为“增强”)。

在这个控制器的增强处理中,spring提供了三个注解,来帮助我们对Controller进行增强的操作:

@ExceptionHandler:异常处理器、@InitBinder:初始参数绑定器、@ModelAttribute(模型参数)。

@ControllerAdvice

先来看下@ControllerAdvice的内容,这个注解是使用在Class上,里面有几个参数可以指定basePackages,但由于这个注解只是对Controller的增强,因此只对指定包下的Controller生效(如果在dao或service包中对异常上抛,也是可以抛出到Controller层,并通过搭配该注解进行捕获异常)。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
@AliasFor("basePackages")
String[] value() default {}; @AliasFor("value")
String[] basePackages() default {}; Class<?>[] basePackageClasses() default {}; Class<?>[] assignableTypes() default {}; Class<? extends Annotation>[] annotations() default {};
}

@ExceptionHandler

@ExceptionHandler:这个注解是使用在方法上,可以处理指定的异常。假如异常不在这个范围内,则不会被捕获,可以定义多个不同的异常处理器用来分别处理不同的异常。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
Class<? extends Throwable>[] value() default {};
}

我们来测试一下@ExceptionHandler

定义一个全局异常处理器,里面指定了两个异常的捕获和处理,一个是IAE,一个是NPE。

@ControllerAdvice
public class GlobalExceptionHandler { @ExceptionHandler(value = IllegalArgumentException.class) //指定异常只处理IAE,也可以指定为Throwable类,可以处理所有的异常。
@ResponseBody //这里添加ResponseBody是为了直接返回字符串到前端,否则会如同Controller一样,将返回的字符串作为视图名处理,向视图发起请求。
public String handler(Exception exception) {
System.out.println("抓住异常,异常原因:");
System.out.println(exception.getMessage());
return "IllegalArgumentException";
} @ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public String handler2(Exception exception) {
System.out.println("抓住异常,异常原因:");
System.out.println(exception.getMessage());
return "NullPointerException";
} }

然后我们定义一个Controller,里面会抛出上面的两种异常

    @GetMapping("users/{id}")
public String getUser(@PathVariable("id") String id) throws Exception {
System.out.println("接收到请求[/users/" + id + "]");
if (id.equals("error")) {
throw new IllegalArgumentException("参数错误!");
} else if (id.equals("null")) {
throw new NullPointerException("id不能为null!");
}
return "testUser";
}

启动项目,分别输入参数为error和null的请求,查看控制台打印数据:

接收到请求[/users/error]
抓住异常,异常原因:
参数错误! 接收到请求[/users/error]
抓住异常,异常原因:
id不能为null!

如果我们在controller里面再抛出一个其他类型的异常,则会直接返回到前端,而不是被交给异常处理器处理。

@InitBinder

这个注解用来对从前端传入的参数进行功能辅助。

具体的辅助功能有很多种。比如我们传了一个String类型的"2019-05-05",但是我们在controller要用Date来获取,默认情况下是会抛出非法参数异常,如下:

因此这个时候需要我们在@InitBinder中配置一个自定义日期格式,如下:

    @InitBinder
public void globalInitBinder(WebDataBinder binder) {
binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
}

这个注解关键的重点在于它的参数WebDataBinder中配置的信息,除了上面的添加自定义格式外,还可以注册其他的类型,如将参数自动存储在Map中。

    @InitBinder
public void globalInitBinder(WebDataBinder binder) {
binder.registerCustomEditor(Integer.class, new CustomMapEditor(HashMap.class));
}

@ModelAttribute

该注解用来在Controller接收参数之前对数据模型进行处理,可以添加或删除相关的数据,比如我们在@ModelAttrbute中配置两个数据name和age

    @ModelAttribute
public void model(Model model) {
model.addAttribute("name", "yxf");
model.addAttribute("age", );
}

然后在Controller的方法中进行配置

    @GetMapping("users/login")
public String test(@ModelAttribute("name")String name, @ModelAttribute("age") int age) {
System.out.println("Name="+name + ";Age="+age);
return "index";
}

配置完成后运行启动类,输入路径"/users/login"不带任何参数。

控制台照样会打印结果:Name=yxf;Age=12

Spring boot--控制器增强的更多相关文章

  1. springboot2.0(一):【重磅】Spring Boot 2.0权威发布

    就在昨天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误, ...

  2. 业余草分享 Spring Boot 2.0 正式发布的新特性

    就在昨天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误, ...

  3. 【重磅】Spring Boot 2.0权威发布

    新版本特性 新版本值得关注的亮点有哪些: 基于 Java 8,支持 Java 9 也就是说Spring Boot2.0的最低版本要求为JDK8,据了解国内大部分的互联网公司系统都还跑在JDK1.6/7 ...

  4. (转)Spring Boot 2(一):【重磅】Spring Boot 2.0权威发布

    http://www.ityouknow.com/springboot/2018/03/01/spring-boot-2.0.html 就在今天Spring Boot2.0.0.RELEASE正式发布 ...

  5. Spring Boot 2(一):Spring Boot 2.0新特性

    Spring Boot 2(一):Spring Boot 2.0新特性 Spring Boot依赖于Spring,而Spring Cloud又依赖于Spring Boot,因此Spring Boot2 ...

  6. spring boot 2.0(一)权威发布spring boot2.0

    Spring Boot2.0.0.RELEASE正式发布,在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误,然后Spring ...

  7. Spring Boot 2(一):【重磅】Spring Boot 2.0权威发布

    就在今天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误, ...

  8. Spring Boot 非常好的学习资料

    from@https://gitee.com/didispace/SpringBoot-Learning Spring Boot 2.0 新特性学习 简介与概览 Spring Boot 2.0 正式发 ...

  9. spring boot学习01【搭建环境、创建第一个spring boot项目】

    1.给eclipse安装spring boot插件 Eclipse中安装Spring工具套件(STS): Help -> Eclipse Marketplace... 在Search标签或者Po ...

  10. Spring Boot (八): Mybatis 增强工具 MyBatis-Plus

    1. 简介 在上一篇文章<Spring Boot (七): Mybatis极简配置> 中我们介绍了在 Spring Boot 中 Mybatis 的基础使用方式,其中有一部分美中不足的是 ...

随机推荐

  1. Markdown 格式标记符号说明

    Markdown 格式标记符号说明 1. 标题 在行首插入 1 到 6个#,分别表示标题 1 到标题 6 # 这是标题1 ## 这是标题1 ###### 这是标题6 点击保存后的效果: 标题1 标题2 ...

  2. 【论文翻译】NIN层论文中英对照翻译--(Network In Network)

    [论文翻译]NIN层论文中英对照翻译--(Network In Network) [开始时间]2018.09.27 [完成时间]2018.10.03 [论文翻译]NIN层论文中英对照翻译--(Netw ...

  3. sql语句怎么看效率?

    1.数据库设计当面: 对查询进行优化,应该尽量避免全表扫描,首先应考虑在where及order by设计的列上加索引. d.索引并不是越多越好,索引可以提高查询效率,同时降低了insert和updat ...

  4. 初识类(class&struct)及C/C++封装的差异

    初识类(class&struct) 面向对象三大特性:封装.继承和多态.其中不得不谈的就是类,通过类创建一个对象的过程叫实例化,实例化后使用对象可以调用类成员函数和成员变量,其中类成员函数称为 ...

  5. hibernate和jdbc的区别 优缺点

    JDBC与Hibernate在性能上相比,JDBC灵活性有优势.而Hibernate在易学性,易用性上有些优势.当用到很多复杂的多表联查和复杂的数据库操作时,JDBC有优势. 相同点: ◆两者都是JA ...

  6. <form>(表单)标签和常用的类型

    1.定义和用法 <form> 标签用于为用户输入创建 HTML 表单. 表单能够包含 input 元素,比如文本字段.复选框.单选框.提交按钮等等. 表单还可以包含 menus.texta ...

  7. mysql 如果处理货币金钱类型

    我们知道,数据库存金钱类型可以float.double.decimal ,相比较而已decimal 最好用. 好吧, 我们公司用的分为单位, 类型 用bigint 存取,操作的时候到是很方便, 展示的 ...

  8. bootstrab table+表格 select可编辑完整实例

    先看下效果图: ============================================================================================ ...

  9. WPF 线程中异常导致程序崩溃

    一般我们WPF中都加全局捕获,避免出现异常导致崩溃. Application.Current.DispatcherUnhandledException += Current_DispatcherUnh ...

  10. LeetCode409Longest Palindrome最长回文串

    给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串. 在构造过程中,请注意区分大小写.比如 "Aa" 不能当做一个回文字符串. 注意: 假设字符串的长度不 ...