SpringMvc提供了拦截器机制,允许允许目标方法之前进行一些拦截工作,或者目标方法运行之后执行一些操作;
Filter: 是JavaWeb里面的
HandlerInterceptor: 是SpringMvc里面的一个接口
PreHandle:在目标方法运行之前调用该方法;返回的是一个boolean类型的变量,如果是true就放行,如果是false就不放行。
PostHandle::在目标方法运行之后调用该方法
AfterCompletion:在请求完成来到目标页面的之后运行该方法。
(1)拦截器是一个接口
(2)实现HandlerInterceptor接口
package controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
* @author JinJian
* @version 1.0
* @date 2021/12/4 20:15
*/
public class MyFirstInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyFirstInterceptor---preHandle********");
return true;
}
@Override
public void postHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyFirstInterceptor----postHandle********");
}
@Override
public void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyFirstInterceptor----afterCompletion********");
}
}
(3)配置拦截器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 开始扫描包 -->
<context:component-scan base-package="controller" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 将jsp页面放置在web-info中可以保护这些页面不被浏览器直接访问 -->
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp"/>
</bean>
<!-- 测试拦截器 -->
<mvc:interceptors>
<!-- 配置某个拦截器,默认是拦截所有请求的 -->
<!--<bean class="controller.MyFirstInterceptor"></bean>-->
<!-- 配置某个拦截器 -->
<mvc:interceptor>
<!-- 只拦截/Test请求 -->
<mvc:mapping path="/Test"/>
<bean class="controller.MyFirstInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
(4)拦截器的运行流程
正常的运行流程:拦截器的preHandle方法-------目标方法——拦截器的postHandle方法------页面-----拦截器的afterCompletion方法
MyFirstInterceptor---preHandle******** 目标方法调用之前运行
test01方法被调用了*****
MyFirstInterceptor----postHandle******** 目标方法调用之后运行
SUCCESS.jsp*****
MyFirstInterceptor----afterCompletion********到达页面之后运行
其他流程:
(1)只要preHandle方法返回false,后面的流程就不会执行了,只会执行preHandle()方法
(2)如果目标方法报错,后面的流程也不会走了
多个拦截器:
正常流程:
<mvc:interceptors> <!-- 配置某个拦截器,默认是拦截所有请求的 --> <bean class="controller.MyFirstInterceptor"></bean> <!-- 配置某个拦截器 --> <mvc:interceptor> <!-- 只拦截/Test请求 --> <mvc:mapping path="/Test"/> <bean class="controller.MySeconedInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
谁先配置就先运行谁的preHandle方法,但是后面的postHandle()和afterCompletion()方法的执行顺序是反过来的
MyFirstInterceptor---preHandle********
MySeconedInterceptor---preHandle********
test01方法被调用了*****
MySeconedInterceptor---postHandle********
MyFirstInterceptor----postHandle********
SUCCESS.jsp*****
MySeconedInterceptor---afterCompletion********
MyFirstInterceptor----afterCompletion********
异常情况:
(1)不放行:哪一个拦截器不放行,后面的流程都不会执行
(2)如果后面的拦截器不放行,前面的拦截器放行了前面拦截器的afterCompletion()都会执行
如MyFirstInterceptor放行而MySeconedInterceptor不放行,但是MyFirstInterceptor的afterCompletion()方法还是会执行的
MyFirstInterceptor---preHandle********
MySeconedInterceptor---preHandle********
MyFirstInterceptor----afterCompletion********
拦截器的流程和Filter的流程是一样的,