SpringMVC拦截器
llp1110 人气:01.什么是拦截器
说明
- Spring MVC 也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能.
- 自定义的拦截器必须实现 HandlerInterceptor 接口
自定义拦截器的三个方法
- preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理。
- postHandle():这个方法在目标方法处理完请求后执行
- afterCompletion():这个方法在完全处理完请求后被调用,可以在该方法中进行一些资源 清理的操作。
2.自定义拦截器执行流程图
自定义拦截器执行流程说明
- 如果 preHandle 方法 返回 false, 则不再执行目标方法, 可以在此指定返回页面
- postHandle 在目标方法被执行后执行. 可以在方法中访问到目标方法返回的 ModelAndView 对象
- 若 preHandle 返回 true, 则 afterCompletion 方法 在渲染视图之后被执行.
- 若 preHandle 返回 false, 则 afterCompletion 方法不会被调用
- 在配置拦截器时,可以指定该拦截器对哪些请求生效,哪些请求不生效,如果不配置默认对所有请求生效
3.自定义拦截器应用实例
1.快速入门
● 应用实例需求
完成一个自定义拦截器,学习一下如何配置拦截器和拦截器的运行流程
● 应用实例-代码实现
1.自定义拦截器
/** * 自定义拦截器 */ @Component public class MyInterceptor01 implements HandlerInterceptor { /** * 1.preHandle 方法在目标方法执行前被执行 * 2.如果返回fasle则不在执行目标方法 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor01 --preHandle"); return true; } /** * 1. 在目标方法执行后,会执行postHandle * 2. 该方法可以获取到 目标方法,返回的ModelAndView对象 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor01-postHandle"); } /** *1. afterCompletion() 在视图渲染后被执行, 这里可以进行资源清理工作 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor01-afterCompletion"); } }
2.配置拦截器
拦截配置有三种方式
(1)不指定拦截规则,默认拦截所有
<!--配置自定义拦截器-spring配置文件--> <mvc:interceptors> <!--第一种方式,不指定拦截规则默认拦截所有请求--> <ref bean="myInterceptor01"></ref> </mvc:interceptors>
(2)指定明确的拦截路径
<!--配置自定义拦截器-spring配置文件--> <mvc:interceptors> <!--第一种方式,不指定拦截规则默认拦截所有请求--> <!--<ref bean="myInterceptor01"></ref>--> <!--第二种指定拦截路径--> <mvc:interceptor> <mvc:mapping path="/hi"/> <ref bean="myInterceptor01"/> </mvc:interceptor> </mvc:interceptors>
(3)通配符方式,也可用于指定不拦截路径
<!--配置自定义拦截器-spring配置文件--> <mvc:interceptors> <!--第一种方式,不指定拦截规则默认拦截所有请求--> <!--<ref bean="myInterceptor01"></ref>--> <!--第二种指定拦截路径--> <!-- <mvc:interceptor> <mvc:mapping path="/hi"/> <ref bean="myInterceptor01"/> </mvc:interceptor>--> <mvc:interceptor> <!--通配符方式 表示拦截 /h 打头的路径--> <mvc:mapping path="/h*"/> <!--/hello不拦截--> <mvc:exclude-mapping path="/hello"/> <!--指定对哪个拦截器配置--> <ref bean="myInterceptor01"/> </mvc:interceptor> </mvc:interceptors>
3.创建FurnHandler.java
@Controller public class FurnHandler { @RequestMapping(value = "/hi") public String hi(User user) { System.out.println("---FurnHandler--hi()---"); return "success"; } @RequestMapping(value = "/hello") public String hello() { System.out.println("---FurnHandler--hello()---"); return "success"; } @RequestMapping(value = "/ok") public String ok() { System.out.println("---FurnHandler--ok()---"); return "success"; } }
4.interceptor.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>测试自定义拦截器</title> </head> <body> <h1>测试自定义拦截器</h1> <a href="<%=request.getContextPath()%>/hi" rel="external nofollow" >测试自定义拦截器-hi</a><br><br> <a href="<%=request.getContextPath()%>/hello" rel="external nofollow" >测试自定义拦截器-hello</a><br/><br/> <a href="<%=request.getContextPath()%>/ok" rel="external nofollow" >测试自定义拦截器-ok</a><br><br> </body> </html>
5.测试
2.注意事项和细节
1、默认配置是都所有的目标方法都进行拦截, 也可以指定拦截目标方法, 比如只是拦截 hi
<mvc:interceptor> <mvc:mapping path="/hi"/> <ref bean="myInterceptor01"/> </mvc:interceptor>
2、mvc:mapping 支持通配符, 同时指定不对哪些目标方法进行拦截
<mvc:interceptor> <mvc:mapping path="/h*"/> <mvc:exclude-mapping path="/hello"/> <ref bean="myInterceptor01"/> </mvc:interceptor>
3、拦截器需要配置才生效,不配置是不生效的.
4、如果 preHandler() 方法返回了 false, 就不会执行目标方法(前提是你的目标方法被拦截 了), 程序员可以在这里根据业务需要指定跳转页面.
3.Debug执行流程
4.多个拦截器
1.多个拦截器执行流程示意图
执行流程可以参考filter过滤器,执行顺序根据配置的先后顺序
2.应用实例
代码实现
新增拦截器
@Component public class MyInterceptor02 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor02-preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor02-postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor02-afterCompletion"); } }
配置拦截器
<!--配置自定义拦截器-spring配置文件--> <mvc:interceptors> <!--第一种方式,不指定拦截规则默认拦截所有请求--> <!--<ref bean="myInterceptor01"></ref>--> <!--第二种指定拦截路径--> <!-- <mvc:interceptor> <mvc:mapping path="/hi"/> <ref bean="myInterceptor01"/> </mvc:interceptor>--> <mvc:interceptor> <!--通配符方式 表示拦截 /h 打头的路径--> <mvc:mapping path="/h*"/> <!--/hello不拦截--> <mvc:exclude-mapping path="/hello"/> <!--指定对哪个拦截器配置--> <ref bean="myInterceptor01"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/hi"/> <ref bean="myInterceptor02"/> </mvc:interceptor> </mvc:interceptors>
这里我们定义了两个拦截器myInterceptor01和myInterceptor02,两个拦截器都会对ip:port/工程路径/hi的请求进行拦截,执行结果如下图所示:
执行流程说明:拦截器的执行先后顺序根据配置的先后顺序执行
3.主要事项和细节
- 如果第 1 个拦截器的 preHandle() 返回 false , 后面都不在执行
- 如果第2个 拦 截 器 的 preHandle() 返 回 false , 就 直 接 执 行 第1个 拦 截 器 的 afterCompletion()方法, 如果拦截器更多,规则类似
- 说明: 前面说的规则,都是目标方法被拦截的前提
在实际开发中我们常用拦截器对登录进行验证
加载全部内容