前期知识

  • 拦截器的作用:拦截器的作用是在服务器处理请求资源之前、之后去做一些事情,比如在处理请求资源之前需要验证一下从前端传入过来的数据合不合规则,处理请求资源之后验证一下有没有发生异常
  • 拦截器的三个方法:

    • preHandle:在处理请求资源之前做的方法

      • 当返回值为true,表示放行,也就是可以处理请求资源
      • 当返回值为false,表示不放行,也就是不能处理请求资源
    • postHandle:在处理请求资源之后做的方法,如果preHandle不放行,那么这个方法也一定不会执行到
    • afterCompletion:是一个最终执行的方法,如果是只有一个拦截器可能看不到效果,但是当有多个拦截器时,会先执行多个拦截器的preHandle和postHandle,然后再执行afterCompletion
  • 拦截器与filter的触发位置:

    • filter:在我们使用Tomcat的时候,它给我们提供了filter过滤器,这个filter的触发位置是位于浏览器和服务器之间,也就是当请求的资源还没到达服务器时,filter就先对请求的资源做处理
    • 拦截器:而拦截器是SpringMVC框架提供的,既然是框架提供的,那么当请求还没到达服务器时SpringMVC是没有办法处理的,也就是当SpringMVC接收到请求之后,它会先把请求资源交给拦截器,然后再放行给处理具体请求资源的Servlet类
  • 拦截器与filter的拦截范围

    • filter:什么都能够拦截,既能拦截Servlet资源,也能拦截html,css,jsp等文件
    • 拦截器:只能拦截Servlet资源

一、拦截器的配置与使用

  • 自定义拦截器类

        public class MyInterceptor implements HandlerInterceptor {
            //预先处理,在资源处理前
             @Override
             public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                    System.out.println("interceptor1:资源处理前");
                    return true;//放行
             }
                //后置处理,在资源处理后
             @Override
             public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
                    System.out.println("interceptor1:资源处理后");
             }
                //最终完成后处理
             @Override
             public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
                    System.out.println("interceptor1:最终方法");
             }
        }
  • Controller执行类

    @Controller
    public class UserController {
        @RequestMapping("testIntercept.do")
        public String testIntercept(){
            System.out.println("controller资源处理了");
            return "";
        }
    }
  • JSP

    <%@ page contentType="text/html; charset=UTF-8" language="java" %>
    <html>
    <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>cai jin hong</title>
    </head>
    <body>
     <a href="testIntercept.do">拦截器</a>
    </body>
    </html>
  • Spring配置文件

    <?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:aop="http://www.springframework.org/schema/aop"
     xmlns:mvc="http://www.springframework.org/schema/mvc"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <!-- 手动配置这个类的驱动-->
         <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
        <!-- 配置拦截器-->
         <mvc:interceptors>
             <mvc:interceptor>
                 <mvc:mapping path="/*"/>
                 <bean class="com.cjh.interceptor.MyInterceptor"></bean>
             </mvc:interceptor>
             <mvc:interceptor>
                 <mvc:mapping path="/*"/>
                 <bean class="com.cjh.interceptor.MyInterceptor2"></bean>
             </mvc:interceptor>
         </mvc:interceptors>
    </beans>
  • 执行结果

image

二、拦截器的执行流程

1、一个拦截器

如上面代码所示,

  • 拦截器会先执行preHandle方法,如果preHandle返回的结果为true,那么执行具体执行请求资源的Controller类
  • 然后再执行postHandle方法
  • 最后执行afterCompletion方法

2、多个拦截器

假设有两个拦截器,根据配置信息的配置位置,拦截器1的配置信息在拦截器2的前面,那么首先会执行拦截器1

  • 1)拦截器1先执行preHandle方法

    • 如果preHandle返回true,拦截器2执行preHandle方法,跳到第2步
    • 如果preHandle返回false,拦截器2不执行preHandle方法,跳到第7步
  • 2)当拦截器2的preHandle方法返回:

    • true,执行controller的方法,跳到第3步
    • false,跳到第6步
  • 3)拦截器2执行postHandle方法
  • 4)拦截器1执行postHandle方法
  • 5)拦截器2执行afterCompletion方法
  • 6)拦截器1执行afterCompletion方法
  • 7)结束
  • 注意:只要某个拦截器的preHandle方法放行了(返回true),那么不论它的postHandle方法能不能执行,它的afterCompletion方法一定会执行,这就有点像try{}catch{}finally{}
  • 多个拦截器的代码和单个的是一样的,只是配置的时候需要把每个拦截器都配置进去,每个拦截器是一个interceptor标签对象

cing_self
18 声望3 粉丝