拦截器的配置

article/2025/10/12 12:41:08

文章目录

        • 拦截器简介
        • 实现一个拦截器
        • 拦截器的配置
        • 多个拦截器时的执行顺序

拦截器简介

过滤器可以拦截请求,拦截器也能拦截请求,那过滤器和拦截器有啥区别?看下面这张图就明白了。
在这里插入图片描述
拦截器有三个方法,分别是

  1. preHandle,发生在请求被控制器方法处理前。
    perHandle方法的返回值是boolean类型,true或false。
    true,表示放行,即调用控制器方法。
    false,表示拦截,即不调用控制器方法。
  2. postHandle,发生在请求被控制器方法处理后。
  3. afterCompletion,发生在视图渲染后。

为了更好地理解以上三个方法,可以查阅下DispatcherServlet的源码。
在这里插入图片描述
在这里插入图片描述

实现一个拦截器

现在来实现一个拦截器。
首先,新建一个基本的maven项目,这里不赘述,仅附上部分代码。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<a th:href="@{/testInterceptor}">测试拦截器</a>
</body>
</html>
<!-- success.html -->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
success
</body>
</html>
package com.example.mvc.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class TestController {@RequestMapping("/testInterceptor")public String testInterceptor(){return "success";}
}

然后,在java目录下新建Package:com.example.mvc.interceptors,在该包下新建类FirstInterceptor,内容如下,

package com.example.mvc.interceptors;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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("FirstInterceptor-->preHandle");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("FirstInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("FirstInterceptor-->afterCompletion");}
}

FirstInterceptor实现了接口HandlerInterceptor的perHandle、postHandle和afterCompletion方法。
在这里插入图片描述
接着,在配置文件springMVC.xml中配置拦截器,如下所示,

<mvc:interceptors><bean class="com.example.mvc.interceptors.FirstInterceptor"/>
</mvc:interceptors>

最后,启动应用。
在这里插入图片描述
IDEA控制器仅打印出:FirstInterceptor–>preHandle。这是因为preHandle的返回值是false,表示拦截,即不调用控制器方法,所以后面的postHandle、afterCompletion也不会对请求进行拦截处理。

不妨让preHandle返回true试试,如下,
在这里插入图片描述
IDEA控制台打印出的信息如下:

21:29:47.058 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
21:29:47.138 [http-nio-8080-exec-5] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/interceptor/", parameters={}
21:29:47.138 [http-nio-8080-exec-5] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped to ParameterizableViewController [view="index"]
FirstInterceptor-->preHandle
FirstInterceptor-->postHandle
FirstInterceptor-->afterCompletion
21:29:47.141 [http-nio-8080-exec-5] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
07-Dec-2021 21:29:52.964 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\tomcat\webapps\manager]
07-Dec-2021 21:29:53.017 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\tomcat\webapps\manager]的部署已在[52]毫秒内完成
21:29:56.724 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/interceptor/testInterceptor", parameters={}
21:29:56.736 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.example.mvc.controller.TestController#testInterceptor()
FirstInterceptor-->preHandle
FirstInterceptor-->postHandle
FirstInterceptor-->afterCompletion
21:29:56.782 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK

即,访问根路径/时,IDEA控制台打印了:
FirstInterceptor–>preHandle
FirstInterceptor–>postHandle
FirstInterceptor–>afterCompletion。
访问/testInterceptor时,IDEA控制台也打印了:
FirstInterceptor–>preHandle
FirstInterceptor–>postHandle
FirstInterceptor–>afterCompletion。
也就是说,拦截器FirstInterceptor对所有的浏览器请求都进行了拦截。

拦截器的配置

拦截器的配置方法有三种。

  • 第一种,使用bean。
<mvc:interceptors><bean class="com.example.mvc.interceptors.FirstInterceptor"/>
</mvc:interceptors>
  • 第二种,使用ref。

首先,需要在拦截器的类上添加注解@Component,将该拦截器注册为IoC容器的bean,如下。

package com.example.mvc.interceptors;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class FirstInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("FirstInterceptor-->preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("FirstInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("FirstInterceptor-->afterCompletion");}
}

同时,必须能够扫描到该拦截器,如下。

<context:component-scan base-package="com.example.mvc.controller,com.example.mvc.interceptors"></context:component-scan>

当然,也可以这样写,

<context:component-scan base-package="com.example.mvc"></context:component-scan>

最后,使用ref配置拦截器。

<mvc:interceptors><ref bean="firstInterceptor"/>
</mvc:interceptors>
  • 第三种,使用interceptor。
    第一种、第二种方法,会对浏览器的所有请求进行拦截,不能指定拦截规则。
    使用interceptor时,可以设置拦截规则,指定拦截哪些请求路径,不拦截哪些请求路径。
    <mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><mvc:exclude-mapping path="/"/><ref bean="firstInterceptor"/></mvc:interceptor></mvc:interceptors>

<mvc:mapping path="/**"/>mapping表示要拦截,/**代表所有的请求路径,故拦截所有的请求路径。
<mvc:exclude-mapping path="/"/>exclude-mapping,表示不要拦截,即不拦截根路径。

重启应用,IDEA控制台打印出如下信息:

21:50:23.901 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
21:50:23.978 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/interceptor/", parameters={}
21:50:23.978 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped to ParameterizableViewController [view="index"]
21:50:23.983 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
07-Dec-2021 21:50:29.323 信息 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\tomcat\webapps\manager]
07-Dec-2021 21:50:29.378 信息 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\tomcat\webapps\manager]的部署已在[54]毫秒内完成
21:50:33.199 [http-nio-8080-exec-5] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/interceptor/testInterceptor", parameters={}
21:50:33.211 [http-nio-8080-exec-5] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.example.mvc.controller.TestController#testInterceptor()
FirstInterceptor-->preHandle
FirstInterceptor-->postHandle
FirstInterceptor-->afterCompletion
21:50:33.254 [http-nio-8080-exec-5] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK

访问根路径时,没有打印出信息。
访问/testInterceptor时,打印出如下信息:
FirstInterceptor–>preHandle
FirstInterceptor–>postHandle
FirstInterceptor–>afterCompletion。

多个拦截器时的执行顺序

先说结论:多个拦截器时,它们的执行顺序与SpringMVC配置文件中配置的顺序有关。

  • 情景1:所有的拦截器的preHandle都返回true
    preHandle按照配置的顺序正序执行;
    postHandle、afterCompletion按照配置的顺序反序执行。

看个例子。

package com.example.mvc.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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("FirstInterceptor-->preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("FirstInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("FirstInterceptor-->afterCompletion");}
}
package com.example.mvc.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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("SecondInterceptor-->preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("SecondInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("SecondInterceptor-->afterCompletion");}
}

拦截器FirstInterceptor、拦截器SecondInterceptor的preHandle都返回true。

<mvc:interceptors><bean class="com.example.mvc.interceptor.FirstInterceptor"/><bean class="com.example.mvc.interceptor.SecondInterceptor"/>
</mvc:interceptors>

SpringMVC配置文件,配置拦截器的顺序为:FirstInterceptor->SecondInterceptor,即FirstInterceptor在先,SecondInterceptor在后。

启动应用,IDEA控制台打印出如下信息:

20:45:18.657 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
20:45:18.754 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/interceptor/", parameters={}
20:45:18.754 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped to ParameterizableViewController [view="index"]
FirstInterceptor-->preHandle
SecondInterceptor-->preHandle
SecondInterceptor-->postHandle
FirstInterceptor-->postHandle
SecondInterceptor-->afterCompletion
FirstInterceptor-->afterCompletion
  • 情景2:某个拦截器的preHandle返回false,假定为拦截器A
    拦截器A、A前面的拦截器的preHandle按照配置的顺序正序执行。
    所有拦截器的postHandle都不会执行。
    A前面的拦截器的afterCompletion按照配置的顺序反序执行。

看个例子。

package com.example.mvc.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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("FirstInterceptor-->preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("FirstInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("FirstInterceptor-->afterCompletion");}
}
package com.example.mvc.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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("SecondInterceptor-->preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("SecondInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("SecondInterceptor-->afterCompletion");}
}
package com.example.mvc.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 ThirdInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("ThirdInterceptor-->preHandle");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("ThirdInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("ThirdInterceptor-->afterCompletion");}
}

拦截器FirstInterceptor、拦截器SecondInterceptor的preHandle都返回true,拦截器ThirdInterceptor的preHandle返回false。

<mvc:interceptors><bean class="com.example.mvc.interceptor.FirstInterceptor"/><bean class="com.example.mvc.interceptor.SecondInterceptor"/><bean class="com.example.mvc.interceptor.ThirdInterceptor"/>
</mvc:interceptors>

SpringMVC配置文件中,配置的拦截器的先后顺序为:FirstInterceptor->SecondInterceptor->ThirdInterceptor。

启动应用,IDEA控制器打印出如下信息:

20:44:11.885 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
20:44:11.982 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/interceptor/", parameters={}
20:44:11.982 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped to ParameterizableViewController [view="index"]
FirstInterceptor-->preHandle
SecondInterceptor-->preHandle
ThirdInterceptor-->preHandle
SecondInterceptor-->afterCompletion
FirstInterceptor-->afterCompletion

多拦截器时执行顺序为什么结论如上?其实查阅下DispatcherServlet源码就明白了,不妨调试下。

视频1是针对情景1的调试。

视频1

视频2是针对情景2的调试。

视频2


http://chatgpt.dhexx.cn/article/s48GRKq4.shtml

相关文章

springmvc拦截器

实现拦截器步骤 步骤一 声明拦截器类&#xff08;实现 handlerInterceptor接口&#xff09; 1.主要看prehandle方法的返回值确定是否放行&#xff0c;如果是true&#xff0c;表示放行&#xff0c;会执行该拦截器的prehandle方法&#xff0c; 如果有多个拦截器&#xff0c;…

DateUtils时间类

1、测试 package test.utils.date; import java.text.ParseException; import java.util.Date; import org.apache.commons.lang.time.DateUtils; public class Test {public static void main(String[] args) {int amount 2;Date date new Date();// System.out.printf(&qu…

dateutil模块

安装&#xff1a;终端运行 pip install python-dateutil python第三方模块dateutil模块主要使用以下&#xff0c;1&#xff0c; parse&#xff0c;2&#xff0c;rrule, 3&#xff0c;relativedelta。 parse把字符串格式的时间转化为datetime.datetime格式时间。util是计算时间差…

封装工具类DBUtils、DateUtils详解

三、封装工具类DBUtils、DateUtils 把以下会重复写的代码封装&#xff1a; 3.1 封装货期连接、释放资源两个方法 提供public static Connection getConnection(){}方法。提供public static void closeAll(Connection conn,Statement sm,ResultSet rs){}方法。 3.2 跨平台方…

常用DateUtil

导语 最近项目中用到一些时间的操作&#xff0c;当然我们可以选择lang3&#xff0c;或者其他三方的jar&#xff0c;来进行操作&#xff0c;小编将项目中用到的一些用于的时间工具整理了一下&#xff0c;给大家参考一下! 先给大家展示一下使用及效果 使用 GetMapping(value &…

Android个人学习笔记之实战时间的获取相关-DateUtils

前言&#xff1a;在近期的项目编写过程中&#xff0c;看到了时间工具类DateUtil&#xff0c;虽然大致的用法已经清楚&#xff0c;但是对于这个类还是有一定的不解&#xff0c;很多类型并不知道实际的效果如何&#xff0c;所以就结合Android的API&#xff0c;实战来测试不同的效…

什么是token和使用的意义

一、什么是token token &#xff08;计算机术语&#xff09; 在计算机身份认证中是令牌&#xff08;临时&#xff09;的意思&#xff0c;在词法分析中是标记的意思。一般作为邀请、登录系统使用。 二、token的意义 令牌&#xff1a;代表执行某些操作的权利和对象&#xff0c;访…

Token

Token笔记 是什么SessionCookietoken 为什么Session和Cookie 区别&#xff1a;token和Session区别&#xff1a;Session缺陷token相比而言&#xff1a; 怎么做token工作流程&#xff1a;token结构&#xff1a; 是什么 web应用程序是使用HTTP协议来传送数据的。而HTTP是无状态的…

Java 中 Token 是什么,有哪些用途

简介 Token 是一种身份验证机制&#xff0c;通常由服务器生成并返回给客户端&#xff0c;客户端在后续的请求中携带 Token&#xff0c;以证明自己的身份。在 Java 中&#xff0c;Token 的应用场景非常广泛&#xff0c;例如用户登录、API 认证、OAuth 授权等等。 在用户登录的…

Token的作用及原理

讲到Token的作用和原理&#xff0c;网上有很多相关的技术文章&#xff0c;通过搜集整理并加入自己的理解体会&#xff0c;做一个总结整理&#xff0c;希望可以帮助到更多有需要的人。 1、token作用及原理 Token&#xff0c;即令牌&#xff0c;是服务器产生的&#xff0c;具有…

Token和Jwt的区别

Token基本原理 Token(就是加密的字符串,使用MD5,等不可逆加密算法,一定要保证唯一性) 客户端使用用户名跟密码请求登录 服务端收到请求&#xff0c;去验证用户名与密码 验证成功&#xff0c;服务端会签发一个Token保存到(Session,redis,mysql…)中&#xff0c;然后再把这个 …

什么是token及怎样生成token

什么是token Token是服务端生成的一串字符串&#xff0c;以作客户端进行请求的一个令牌&#xff0c;当第一次登录后&#xff0c;服务器生成一个Token便将此Token返回给客户端&#xff0c;以后客户端只需带上这个Token前来请求数据即可&#xff0c;无需再次带上用户名和密码。 基…

token是什么?

token的意思是令牌&#xff0c;是服务端生成的一串字符串&#xff0c;作为客户端进行请求的一个标识。 当用户第一次登录后&#xff0c;服务器生成一个token&#xff0c;并将token返回给客户端&#xff0c;之后客户端只需要带上这个token前来请求数据即可&#xff0c;无需再带…

Token是什么 Token登录认证

Token 是在服务端产生的一串字符串。如果前端使用用户名/密码向服务端请求认证&#xff0c;服务端认证成功&#xff0c;那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化&#xff08;比如存入数据库&a…

什么是Token(令牌)

Acess Token 访问资源接口&#xff08;API&#xff09;时所需要的资源凭证 简单token 的组成&#xff1a; uid&#xff08;用户唯一的身份标识&#xff09; 、time (当前时间的时间戳) ,sign&#xff08;签名&#xff0c;token的前几位以hash算法压缩成的一定长度的16进制字符…

什么是token?token是用来干嘛的?

相信很多从事计算机行业的朋友都听说过token这么个东西&#xff0c;但是其他行业的人就很少了解到token&#xff0c;下面就给大家来详细介绍一下token是什么意思&#xff1f;token是用来干嘛的这一块的内容&#xff0c;希望能帮助到大家。 &#x1f3fb; token是什么意思 作为…

究竟什么是token??

基于服务器验证方式的验证流程&#xff1a; 我们都是知道HTTP协议是无状态的&#xff0c;这种无状态意味着程序需要验证每一次请求&#xff0c;从而辨别客户端的身份。在这之前&#xff0c;程序都是通过在服务端存储的登录信息来辨别请求的。这种方式一般都是通过存储Session来…

python 处理 MovieLens 数据

文章目录 一、总述二、处理流程1. 处理 users 数据2. 处理 movies 数据3. 处理 ratings 数据4. 将 users、movies 和 ratings 数据合并5. one-hot 处理6. 完整代码 一、总述 该文记录处理 MovieLens-1m 数据集的步骤&#xff0c;首先分别处理用户、电影和评分数据&#xff0c;…

电影数据集总结:Netflix、MovieLens、LDOS-CoMoDa、AdomMovie

数据集&#xff1a; 1.Netflix 描述&#xff1a;包含Netflix上48万多个随机选取的匿名用户&#xff0c;对于1万7千多部电影的1兆多个电影评分 时间&#xff1a;1988.10~2005.11 内容&#xff1a; 包括training set&#xff0c;movie titles&#xff0c;probe set&#xff0…

从IMDB上爬取MovieLens数据集中的详细电影信息

文章目录 基于协同过滤的电影推荐系统数据集HTML页面分析爬虫代码运行时间百度网盘链接 基于协同过滤的电影推荐系统 用这个数据集实现了一个小型的电影推荐网站&#xff0c;GitHub代码 数据集 数据集是MovieLens提供的ml-latest-small https://grouplens.org/datasets/mov…