一、拦截器
-
SpringMVC拦截器作用 用于对处理器(Controller)进行预处理 和后处理。
-
拦截器链 多个拦截器可以按顺序组成一条链,访问被拦截方法时,会按配置顺序执行。
-
拦截器 vs 过滤器
- 过滤器是Servlet规范 的一部分,所有 Web框架都能用
- 拦截器是SpringMVC独有的技术
- 过滤器配置
/*可以拦截所有资源(jsp、css、js、controller) - 拦截器只会拦截Controller方法
- 拦截器是AOP 思想的具体实现
-
自定义拦截器要求 必须实现
HandlerInterceptor接口
二、自定义拦截器步骤
1. 控制器:DeptController.java
java
package cn.tx.demo4;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 测试拦截器
*/
@Controller
@RequestMapping("/dept")
public class DeptController {
/**
* 测试方法
* @return
*/
@RequestMapping("/findAll.do")
public String findAll(){
System.out.println("controller方法执行了...");
return "suc";
}
}
2. 自定义拦截器:MyInterceptor2.java
java
package cn.tx.demo4;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 拦截器类
*/
public class MyInterceptor2 implements HandlerInterceptor{
/**
* 拦截controller中方法。放行了,执行controller中方法。
* return true 放行
* return false 拦截
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器preHandle方法执行了...");
// 手动跳转页面
// request.getRequestDispatcher("/index.jsp").forward(request,response);
// 拦截,不放行
//return false;
// 放行
return true;
}
}
3. 在 springmvc.xml 中配置拦截器
java
<!--配置拦截器们-->
<mvc:interceptors>
<!--配置拦截器-->
<mvc:interceptor>
<!--该拦截器拦截哪些资源-->
<mvc:mapping path="/dept/**"/>
<!--哪些资源不想拦截
<mvc:exclude-mapping path="" />
-->
<!--拦截器对象-->
<bean class="cn.tx.demo4.MyInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>
三、HandlerInterceptor 接口中的 3 个方法
1. preHandle( )
- Controller 方法执行前调用
return true:放行,执行下一个拦截器 / Controllerreturn false:拦截,不执行 Controller- 可以使用
request/response跳转页面
2. postHandle( )
- Controller 方法执行后,JSP 渲染前调用
- 可以修改
ModelAndView,改变跳转页面 - 若手动跳转,Controller 指定页面不会显示
3. afterCompletion( )
- JSP 页面执行完毕后,最后执行
- 一般用于资源清理
- 不能再跳转页面
完整 3 个方法的拦截器:MyInterceptor2.java
java
package cn.tx.demo4;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 拦截器类
*/
public class MyInterceptor2 implements HandlerInterceptor{
/**
* 拦截controller中方法。放行了,执行controller中方法。
* return true 放行
* return false 拦截
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器preHandle方法执行了...");
return true;
}
/**
* controller方法执行后,要拦截的方法
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle方法执行了...");
// 可以进行页面的跳转
// request.getRequestDispatcher("/index.jsp").forward(request,response);
}
/**
* controller跳转的jsp页面都执行完成了,最后执行该方法
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion方法执行了...");
}
}
四、配置多个拦截器(拦截器链)
1. 第二个拦截器:MyInterceptor3.java
java
package cn.tx.demo4;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 拦截器类
*/
public class MyInterceptor3 implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor3的preHandle方法执行了...");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor3的postHandle方法执行了...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor3的afterCompletion方法执行了...");
}
}
2. springmvc.xml 配置两个拦截器
java
<!--配置拦截器们-->
<mvc:interceptors>
<!--配置拦截器1-->
<mvc:interceptor>
<mvc:mapping path="/dept/**"/>
<bean class="cn.tx.demo4.MyInterceptor2" />
</mvc:interceptor>
<!--配置拦截器2-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.tx.demo4.MyInterceptor3" />
</mvc:interceptor>
</mvc:interceptors>
五、多拦截器执行顺序
-
preHandle:顺序执行拦截器 1 → 拦截器 2 → Controller
-
postHandle:逆序执行Controller → 拦截器 2 → 拦截器 1
-
afterCompletion:逆序执行页面渲染完 → 拦截器 2 → 拦截器 1
六、运行控制台输出
java
拦截器preHandle方法执行了...
MyInterceptor3的preHandle方法执行了...
controller方法执行了...
MyInterceptor3的postHandle方法执行了...
postHandle方法执行了...
MyInterceptor3的afterCompletion方法执行了...
afterCompletion方法执行了...