玩转 SpringBoot 2 快速整合拦截器
概述
首先声明一下,这里所说的拦截器是 springmvc 的拦截器 handlerinterceptor。使用springmvc 拦截器需要做如下操作:
- 创建拦截器类需要实现 handlerinterceptor
- 在 xml 配置文件中配置该拦截器,具体配置代码如下:
<mvc:interceptors> <mvc:interceptor> <!-- /test/** 这个是拦截路径以/test开头的所有的url--> <mvc:mapping path="/**"/><!—这个是拦截说有的路径--> <!-- 配置拦截器类路径--> <bean class="cn.ljk.springmvc.controller.myinterceptor"></bean> <!-- 配置不拦截器url路径--> <mvc:exclude-mapping path="/fore/**"/> </mvc:interceptor> </mvc:interceptors>
因为在springboot 中没有 xml 文件,所以springboot 为我们提供 java config 的方式来配置拦截器。配置方式有2种:
- 继承 webmvcconfigureradapter (官方已经不建议使用)
- 实现 webmvcconfigurer
接下来开始 springboot 整合拦截器操作详细介绍!
整合拦截器实战操作
第一步:声明拦截器类
通过实现 handlerinterceptor 来完成。具体代码如下:
public class logininterceptor implements handlerinterceptor{}
第二步:实现 handlerinterceptor 3 个拦截方法
- prehandle:controller逻辑执行之前进行拦截
- posthandle:controller逻辑执行完毕但是视图解析器还为进行解析之前进行拦截
- aftercompletion:controller逻辑和视图解析器执行完毕进行拦截
实际开发中 prehandle使用频率比较高,posthandle 和 aftercompletion操作相对比较少。
在下面的代码中 prehandle 方法中定义拦截所有访问项目 url并进行日志信息记录。posthandle 中在视图解析前进行拦截,通过 model 在次添加数据request域中。
aftercompletion 暂时没有想到使用场景,如果有使用过的场景可以在下面评论区中进行评论。
拦截器详细代码如下:
public class logininterceptor implements handlerinterceptor{ private logger log = loggerfactory.getlogger(logininterceptor.class); //controllercontroller逻辑执行之前 public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { log.info("prehandle...."); string uri = request.getrequesturi(); log.info("uri:"+ uri); if (handler instanceof handlermethod) { handlermethod handlermethod = (handlermethod) handler; log.info("拦截 controller:"+ handlermethod.getbean().getclass().getname()); log.info("拦截方法:"+handlermethod.getmethod().getname()); } return true; } //controller逻辑执行完毕但是视图解析器还为进行解析之前 @override public void posthandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, modelandview modelandview) throws exception { log.info("posthandle...."); map<string,object>map=modelandview.getmodel(); map.put("msg","posthandle add msg"); } //controller逻辑和视图解析器执行完毕 @override public void aftercompletion(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, exception e) throws exception { log.info("aftercompletion...."); } }
第三步:java config 的方式来配置拦截器
继承 webmvcconfigureradapter 方式
通过继承 webmvcconfigureradapter并重写 addinterceptors方法,通过其参数 interceptorregistry将拦截器注入到 spring的上下文中。
另外拦截路径和不拦截的路径通过interceptorregistry 的 addpathpatterns和 excludepathpatterns方法进行设置。
这种方式官方已经不建议使用,因为官方已将 webmvcconfigureradapter 标记为@deprecated 了。
@deprecated public abstract class webmvcconfigureradapter implements webmvcconfigurer {
继承 webmvcconfigureradapter 方式具体代码如下:
@configuration public class interceptorconfigbyextendswebmvcconfigureradapter extends webmvcconfigureradapter{ @bean public logininterceptor logininterceptor(){ return new logininterceptor(); } public void addinterceptors(interceptorregistry registry) { registry.addinterceptor(logininterceptor()).addpathpatterns("/**").excludepathpatterns("/*.html"); } }
实现 webmvcconfigurer 方式
通过实现 webmvcconfigurer 接口并实现 addinterceptors方法,其他操作和继承 webmvcconfigureradapter方式一样。具体代码如下:
```java @configuration public class interceptorconfigbyimplwebmvcconfigurer implements webmvcconfigurer{ @bean public logininterceptor logininterceptor(){ return new logininterceptor(); } @override public void addinterceptors(interceptorregistry registry) { registry.addinterceptor(logininterceptor()).addpathpatterns("/**").excludepathpatterns("/*.html"); } } ```
测试
编写普通controller,具体代码如下:
@controller public class indexcontroller { @getmapping("/index") public string index(modelandview modelandview){ return "index"; } }
在 src/main/resource 下的 templates目录下创建 indexcontroller访问页面 index.ftl, 代码如下:
<h1>${msg}</h1>
由于我这里使用的是 freemarker当页面使用,说以需要引入 freemarker starter依赖,具体点如下:
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-freemarker</artifactid> </dependency>
通过游览器访问 localhost:8080/sbe/index,具体访问效果如下:
如上图所示在视图解析前通过 model在次添加数据到 request域中的msg 成功显示出来了!
日志输出信息如下:拦截地址和拦截controller 和具体方法进行日志输出
2019-09-24 15:53:04.144 info 7732 --- [nio-8080-exec-1] o.a.c.c.c.[tomcat].[localhost].[/sbe] : initializing spring dispatcherservlet 'dispatcherservlet' 2019-09-24 15:53:04.145 info 7732 --- [nio-8080-exec-1] o.s.web.servlet.dispatcherservlet : initializing servlet 'dispatcherservlet' 2019-09-24 15:53:04.153 info 7732 --- [nio-8080-exec-1] o.s.web.servlet.dispatcherservlet : completed initialization in 8 ms 2019-09-24 15:53:04.155 info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor : prehandle.... 2019-09-24 15:53:04.155 info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor : uri:/sbe/index 2019-09-24 15:53:04.155 info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor : 拦截 controller:cn.lijunkui.controller.indexcontroller 2019-09-24 15:53:04.155 info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor : 拦截方法:index 2019-09-24 15:53:04.156 info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor : posthandle.... 2019-09-24 15:53:04.161 info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor : aftercompletion....
小结
springboot 2 整合拦截器和整合 filter的操作很像,都是通过一个注册类将其注入到spring的上下文中,只不过filter使用的是 filterregistrationbean 而 拦截器使用的是 interceptorregistry。
个人觉得比使用 xml 配置的方式更为简单了,如果你还没有在 springboot 项目中使用过拦截器,赶快来操作一下吧!
代码示例
具体代码示例请在我的github 仓库 springbootexamples 中模块名为 spring-boot-2.x-interceptor 项目中进行查看
github:https://github.com/zhuoqianmingyue/springbootexamples
推荐阅读
-
详解SpringBoot结合swagger2快速生成简单的接口文档
-
SpringBoot2 整合 Zookeeper组件,管理架构中服务协调
-
SpringBoot2.x整合Shiro出现cors跨域问题(踩坑记录)
-
SpringBoot2 整合Nacos组件,环境搭建和入门案例详解
-
SpringBoot 2.x 开发案例之 Shiro 整合 Redis
-
玩转 SpringBoot 2 之整合 JWT 上篇
-
玩转 SpringBoot 2 之整合 JWT 下篇
-
玩转 SpringBoot 2 快速整合拦截器
-
基于SpringBoot整合oauth2实现token认证
-
SpringBoot(六) SpringBoot整合Swagger2(自动化生成接口文档)