文章目录
SpringMVC之拦截器
1. 拦截器概述
注意拦截器和过滤器的区别:过滤器先执行,可以理解为拦截器是过滤器的升级版。
SpringMVC有很多默认的拦截器我们使用SpringMVC的时候就使用了,如果我们想自定义拦截器可以通过下面方式实现。
自定义拦截器:SpringMVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现
HandlerInterceptor接口
,也可以继承HandlerInterceptorAdapter 适配器类
public interface HandlerInterceptor { // 在目标方法运行之前调用,返回boolean,return true 放行,return false;不放行。 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; // 在目标方法运行之后调用。 void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; // 在请求整个完成之后,即资源响应之后。 void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
2. 自定义拦截器流程
-
搭建SpringMVC的环境,
配置springMVC.xml和web.xml
。 -
web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!--前端控制器--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <!--只不匹配jsp--> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
在
springMVC.xml
中拦截器配置:<context:component-scan base-package="cn.justweb"/> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--注解驱动,自动注入mvc里面的组件--> <mvc:annotation-driven/> <!--自定义拦截器的配置--> <!--先配谁先执行谁--> <mvc:interceptors> <bean class="cn.justweb.interceptor.FirstInterceptor"></bean> <bean class="cn.justweb.interceptor.SecInterceptor"/> </mvc:interceptors>
-
定义一个拦截器
FirstInterceptor
,实现HandlerInterceptor
接口,并重写其中的三个方法。 -
第一个拦截器
//配置的第一个拦截器 public class FirstInterceptor implements HandlerInterceptor { /** * 执行流程: * 拦截器的preHandle方法执行了 * controller中的testInterceptor方法 * 拦截器postHandle方法执行了 * 拦截器的afterCompletion执行了 * */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("拦截器的preHandle方法执行了"); //此处为true的时候才执行下面的事情 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("拦截器postHandle方法执行了"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("拦截器的afterCompletion执行了"); } }
-
第二个拦截器
//配置的第二个拦截器 public class SecInterceptor implements HandlerInterceptor { /** * 执行流程: * 拦截器的preHandle方法执行了 * 拦截器2的preHandle方法执行了 * controller中的testInterceptor方法 * 拦截器2的postHandle方法执行了 * 拦截器postHandle方法执行了 * 拦截器2的afterCompletion方法执行了 * 拦截器的afterCompletion执行了 * */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("拦截器2的preHandle方法执行了"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("拦截器2的postHandle方法执行了"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("拦截器2的afterCompletion方法执行了"); } }
-
测试
@Controller public class SpringMVCHandler { @RequestMapping("/testInterceptor")//拦截器 public String testInterceptor(){ System.out.println("controller中的testInterceptor方法"); return "success"; } }
3. 拦截器小结
3.1 自定义拦截器
- 实现接口: HandlerInterceptor
- 继承 HandlerInterceptorAdaptor
3.2 单个拦截器中的三个方法
preHandle:在调用处理方法之前执行 dispatcherServlet类中939行
postHandle:在调用处理方法之后执行 dispatcherServlet类中954行
afterCompletion:在mv执行渲染后执行 dispatcherServlet类中1030行
3.3 多个拦截器的执行顺序
-
1.拦截器的执行顺序由配置的顺序决定,先配置拦截器,然后再运行执行。
-
2.拦截器方法的执行顺序
-
/* * 执行流程: * 拦截器的preHandle方法执行了 * 拦截器2的preHandle方法执行了 * controller中的testInterceptor方法 * 拦截器2的postHandle方法执行了 * 拦截器postHandle方法执行了 * 拦截器2的afterCompletion方法执行了 * 拦截器的afterCompletion执行了 */
-
-
preHandle:与配置的的顺序一致
-
postHandle:与配置的顺序相反
-
afterCompletion:与配置的顺序相反
4. Filter和拦截器
4.1 什么时候用Filter什么时候用拦截器?
如果某些功能,需要其他组件配合完成,我们就使用拦截器,其他情况可以写Filter。