拦截器是Spring MVC的组件,可以在进入请求方法之前执行某些操作,也可以在请求方法之后或渲染视图之后执行某些操作。
拦截器的定义
SpringMVC的拦截器只需安装并配置HandlerInterceptor界面即可。 HandlerInterceptor界面的定义如下。
publicinterfacehandlerinterceptor { defaultbooleanprehandle (httpservletrequestrequest,HttpServletResponse response, object ) } defaultvoidposthandle (httpservletrequestrequest,HttpServletResponse response,Object handler, @ nullablemodelandviewmodelandview (throws exception { } defaultvoidaftercompletion ) httpservletrequestrequest,http servlet @ nullableexceptionex (throws exception { } handler interceptor有三种方法,各自的含义如下:
preHandler :在进入请求方法之前执行;
postHandler :在请求方法执行完成后执行;
afterCompletion :在视图渲染后执行。
拦截器的执行流程
在preHandle方法中,返回值为boolean类型,它影响请求方法以及postHandle和afterCompletion的执行。 具体情况如下。
也就是说,如果在preHandle中返回false,则后续进程将不再运行,这可能也是拦截器命名的由来。
测试拦截器
写一个简单的拦截器,代码如下:
@ sl F4 jpublicclasstestinterceptorimplementshandlerinterceptor { @ overridepublicbooleanprehandle (httpservletrequestrequest,) 返回真; } @ overridepublicvoidposthandle (httpservletrequestrequest,HttpServletResponse response,Object handler, modelandview modeler } @ overridepublicvoidaftercompletion (httpservletrequestrequest,HttpServletResponse response,object hact 您为实现Exception ex HandlerInterceptor的所有接口的TestInterceptor创建了侦听器类。 写完TestInterceptor后需要注册。 代码如下所示。
@ configurationpublicclassinterceptorconfigimplementswebmvcconfigurer { @ overridepublicvoidaddinterceptors (intercerceptoreptoreregisioral ) 代码如下所示。
@getmapping(test ) (public String test ) ) return ) test ); 在使用启动和访问项目时,控制台的输出如下所示:
2021-05-0516336002336008.110 info 885
09 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : preHandler2021-05-05 16:02:08.111 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : postHandler2021-05-05 16:02:08.111 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : afterCompletion多个拦截器的执行顺序
我们来写多个相同的监听器,分别是 TestInterceptor、TestInterceptor2 和 TestInterceptor3。然后我们进行注册,注册代码如下:
@Overridepublic void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(testInterceptor()); registry.addInterceptor(testInterceptor2()); registry.addInterceptor(testInterceptor3());}请求我们的方法,输出如下:
2021-05-05 16:09:57.735 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : preHandler2021-05-05 16:09:57.736 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler22021-05-05 16:09:57.736 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : preHandler32021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : postHandler32021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : postHandler22021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : postHandler2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : afterCompletion32021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : afterCompletion22021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : afterCompletion注意观察输出的顺序,preHandle 方法是按注册顺序进行执行的,而 postHandle 和 afterCompletion 跟注册顺序是相反的。
让 preHandle 进行拦截
我们让 TestInterceptor2 的 preHandle 返回值为 false,然后查看一下输出内容。
2021-05-05 16:14:00.997 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : preHandler2021-05-05 16:14:00.998 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler22021-05-05 16:14:00.998 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : afterCompletion可以看到,TestInterceptor2 的 preHandle 的返回值为 false 以后,相当于在 TestInterceptor2 的 preHandle 后续流程则不再继续执行了。
我们调整一下注册的顺序,代码如下:
@Overridepublic void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(testInterceptor2()); registry.addInterceptor(testInterceptor()); registry.addInterceptor(testInterceptor3());}修改顺序后的输出如下:
2021-05-05 16:17:23.956 INFO 88589 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler2可以看到它后面的流程都被拦截了,没有机会执行了。
总结
拦截器是使用一个 List 进行保存,我们可以在项目中添加多个拦截器来完成不同的功能,比如可以进行 Token 的验证,权限的获取等。我们可以放到不同的拦截器中来进行相关的操作。