SpringMVC-自定义拦截器
SpringMVC-自定义拦截器
1.什么是拦截器
● 说明
- 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">测试自定义拦截器-hi</a><br><br>
<a href="<%=request.getContextPath()%>/hello">测试自定义拦截器-hello</a><br/><br/>
<a href="<%=request.getContextPath()%>/ok">测试自定义拦截器-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.应用实例1
1.代码实现
1.新增拦截器
@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");
}
}
2.配置拦截器
<!--配置自定义拦截器-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的请求进行拦截,执行结果如下图所示:
执行流程说明:拦截器的执行先后顺序根据配置的先后顺序执行
2.注意事项和细节
- 如果第 1 个拦截器的 preHandle() 返回 false , 后面都不在执行
- 如 果 第2个 拦 截 器 的 preHandle() 返 回 false , 就 直 接 执 行 第1个 拦 截 器 的 afterCompletion()方法, 如果拦截器更多,规则类似
- 说明: 前面说的规则,都是目标方法被拦截的前提
在实际开发中我们常用拦截器对登录进行验证