0%

SpringMVC的拦截器

  • SpringMVC的拦截器
    • SpringMVC拦截器简介
    • SpringMVC的执行原理
    • 拦截器的实现方式

三、SpringMVC的拦截器

3.1 SpringMVC拦截器简介

  • SpringMVC 中的 Interceptor 拦截器,它的主要作用是拦截指定的用户请求,并进行相应的预处理与后处理。

    其拦截的时间点在 “处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前”。当然,在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。

    • SpringMVC 的拦截器针对请求和响应进行的额外的处理,在请求和响应的过程中添加预处理,后处理和最终处理。
  • 拦截器的应用场景:

    • 日志记录:记录请求信息的日志。
    • 权限检查,如登录检查。
    • 性能检测:检测方法的执行时间。

3.2 SpringMVC的执行原理

![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/SpringMVC/拦截器的执行原理.png)

  • 拦截器执行的时机:

    1. preHandle()

      在请求被处理之前进行操作,预处理

      • 该方法在处理器方法执行之前执行。
      • 其返回值为 boolean,若为 true,则紧接着会执行处理器方法,且会将 afterCompletion() 方法放入到一个专门的方法栈中等待执行。
    2. postHandle()

      在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理

      • 该方法在处理器方法执行之后执行。
      • 处理器方法若最终未被执行,则该方法不会执行。
      • 由于该方法是在处理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。
    3. afterCompletion()

      所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理

      • preHandle() 方法返回 true 时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView 再操作也对响应无济于事。

3.3 拦截器的实现方式

3.3.1 继承HandlerInterceptorAdapter父类

3.3.2 实现HandlerInterceptor接口

  • 推荐使用实现接口的方式。因为在 Java 中类的继承是单一继承,父类的继承应该留给核心业务,而不是交叉业务。

  • 接下来通过实现 HandlerInterceptor 接口的方式来实现一个权限验证拦截器:

    1. 新建一个 SpringMVC-006-interceptor 模块,模块的搭建过程类似于 1.5 ★基于注解的SpringMVC程序 中的流程。

    2. pom.xmlspringmvc.xml 配置文件的内容可以直接看 SpringMVC-learning-code 代码。

    3. webapp 目录下的文件内容也直接看 SpringMVC-learning-code 代码。

    4. 在用户登录功能验证的基础上,添加拦截器功能。

      开发拦截器,实现 HandlerInterceptor 接口,并重写 preHandle() 方法:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      package com.f.springmvc.interceptor;

      import jakarta.servlet.http.HttpServletRequest;
      import jakarta.servlet.http.HttpServletResponse;
      import org.springframework.web.servlet.HandlerInterceptor;

      /**
      * @author fzy
      * @date 2024/2/20 14:44
      */
      public class LoginInterceptor implements HandlerInterceptor {
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
      // 判断是否登录过
      if (request.getSession().getAttribute("user") == null) {
      request.setAttribute("msg", "您还未登录, 请先登录...");
      request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
      return false;
      }
      // 放行请求
      return true;
      }
      }
    5. 然后在 springmvc.xml 配置文件中注册该拦截器:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      <?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 https://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="com.f.springmvc.controller"/>
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/jsp"/>
      <property name="suffix" value=".jsp"/>
      </bean>
      <!--启用注解驱动-->
      <mvc:annotation-driven/>
      <!--注册拦截器-->
      <mvc:interceptors>
      <mvc:interceptor>
      <!--要拦截的请求-->
      <mvc:mapping path="/*"/>
      <!--设置放行的请求-->
      <mvc:exclude-mapping path="/login"/>
      <!--配置具体的拦截器-->
      <bean class="com.f.springmvc.interceptor.LoginInterceptor"/>
      </mvc:interceptor>
      </mvc:interceptors>
      </beans>
    6. 然后该拦截器就能根据配置对指定的请求进行拦截了。类似于 JavaWeb 笔记中的过滤器的作用。

---------------The End---------------