一、定义自己的拦截器
需要我们定义的类继承 HandlerInterceptor 变成自定义的拦截器
- package cn.interceptor;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class FirstInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
- System.out.println("==============MyInterceptor.preHandle()");
- return true;
- }
- @Override
- public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
- System.out.println("===============MyInterceptor.postHandle()");
- }
- @Override
- public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
- System.out.println("================MyInterceptor.afterCompletion()");
- }
- }
二、在 applicationContext.xml 中配置
- mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**" />
- <bean class="cn.interceptor.FirstInterceptor"></bean>
- </mvc:interceptor>
- </mvc:interceptors>
FirstController.java
- package cn.interceptor;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- @Controller
- public class FirstController {
- @RequestMapping("/first.do")
- public String doFirst(){
- return "/index.jsp";
- }
- }
web.xml
- <?xml version="1.0" encoding="UTF-8" ?>
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
- version="3.1">
- <!--核心控制器-->
- <servlet>
- <servlet-name>
- sprigmvc
- </servlet-name>
- <servlet-class>
- org.springframework.web.servlet.DispatcherServlet
- </servlet-class>
- <init-param>
- <param-name>
- contextConfigLocation
- </param-name>
- <param-value>
- classpath:applicationContext.xml
- </param-value>
- </init-param>
- <load-on-startup>
- 1
- </load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>
- sprigmvc
- </servlet-name>
- <url-pattern>
- *.do
- </url-pattern>
- </servlet-mapping>
- </web-app>
流程图
多个拦截器配置就是定义多个拦截器类
在单个拦截器的基础上多添加一个连接器类 SecondInterceptor.java
- package cn.interceptor;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class SecondInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
- System.out.println("===second===========MyInterceptor.preHandle()");
- return true;
- }
- @Override
- public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
- System.out.println("===second============MyInterceptor.postHandle()");
- }
- @Override
- public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
- System.out.println("===second=============MyInterceptor.afterCompletion()");
- }
- }
applicationContext.xml
- <!--配置拦截器-->
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**" />
- <bean class="cn.interceptor.FirstInterceptor">
- </bean>
- </mvc:interceptor>
- <mvc:interceptor>
- <mvc:mapping path="/**" />
- <bean class="cn.interceptor.SecondInterceptor">
- </bean>
- </mvc:interceptor>
- </mvc:interceptors>
流程图
实现 HandlerInterceptor 接口
HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。
(1 )preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顾名思义,该方法将在请求处理之前进行调用。SpringMVC 中的 Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个 Interceptor 。每个 Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是 Interceptor 中的 preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值 Boolean 类型的,当它返回为 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当返回值为 true 时就会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候就会是调用当前请求的 Controller 方法。
(2 )postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由 preHandle 方法的解释我们知道这个方法包括后面要说到的 afterCompletion 方法都只能是在当前所属的 Interceptor 的 preHandle 方法的返回值为 true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是 Controller 方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。postHandle 方法被调用的方向跟 preHandle 是相反的,也就是说先声明的 Interceptor 的 postHandle 方法反而会后执行,这和 Struts2 里面的 Interceptor 的执行过程有点类型。Struts2 里面的 Interceptor 的执行过程也是链式的,只是在 Struts2 里面需要手动调用 ActionInvocation 的 invoke 方法来触发对下一个 Interceptor 或者是 Action 的调用,然后每一个 Interceptor 中在 invoke 方法调用之前的内容都是按照声明顺序执行的,而 invoke 方法之后的内容就是反向的。
(3 )afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的 Interceptor 的 preHandle 方法的返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
来源: