Spring MVC拦截器

news2024/9/23 19:16:42

拦截器(Interceptor)是 Spring MVC 提供的一种强大的功能组件。它可以对用户请求进行拦截,并在请求进入控制器(Controller)之前、控制器处理完请求后、甚至是渲染视图后,执行一些指定的操作。

在 Spring MVC 中,拦截器的作用与 Servlet 中的过滤器类似,它主要用于拦截用户请求并做相应的处理,例如通过拦截器,我们可以执行权限验证、记录请求信息日志、判断用户是否已登录等操作。

Spring MVC 拦截器使用的是可插拔式的设计,如果我们需要某一拦截器,只需在配置文件中启用该拦截器即可;如果不需要这个拦截器,则只要在配置文件中取消应用该拦截器即可。

定义拦截器

想要在 Spring MVC 项目中使用拦截器,第一步就是要对拦截器类进行定义。

Spring MVC 在 org.springframework.web.servlet 包中提供了一个 HandlerInterceptor 接口,该接口包含 3 个方法,如下表。

方法名返回值说明
preHandle () boolean该方法在控制器方法之前执行,其返回值用来表示是否中断后续操作。
  • 返回值为 true 时,表示继续向下执行;
  • 返回值为 false 时,表示中断后续的操作。
postHandle ()void该方法会在控制器方法调用之后,解析式图之前执行。我们可以通过此方法对请求域中的模型(Model)数据和视图做出进一步的修改。
afterCompletion ()void该方法会在整个请求完成后,即视图渲染结束之后执行。我们可以通过该方法实现资源清理、日志记录等工作。

通过实现 HandlerInterceptor 接口,重写其方法,来实现对拦截器类的定义,示例代码如下。


public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle 执行");
        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 执行");
    }
}

配置拦截器

在定义完拦截器后,我们还需要在 Spring MVC 的配置文件中使用 <mvc:interceptors> 标签及其子标签对拦截器进行配置,这样这个拦截器才会生效。

在 Spring MVC 的配置文件中,<mvc:interceptors> 标签用于定义一组拦截器,其包含多个常用的子标签,具体说明如下表。

标签一级子标签二级子标签说明
<mvc:interceptors><bean>-<mvc:interceptors> 标签的子标签,用于定义一个全局拦截器,对所有的请求进行拦截。
<ref>-<mvc:interceptors> 标签的子标签,用于定义一个全局拦截器的引用,对所有的请求进行拦截。

<mvc:interceptors> 标签的 <ref> 子标签不能单独使用,它需要与 <bean> 标签(<mvc:interceptors> 标签内或 <mvc:interceptors>标签外)或 @Component 等注解配合使用,以保证<ref> 标签配置的拦截器是 Spring IOC 容器中的一个组件。
<mvc:interceptor> <mvc:mapping><mvc:interceptor> 标签用于定义一个指定拦截路径的拦截器。

<mvc:mapping> 标签则是<mvc:interceptor> 的子标签,用来配置拦截器拦截的路径,该路径则是通过其属性“path”中定义的。例如,path 的属性值为“/**”时,表示拦截所有请求;而“/hello”则表示拦截路径为“/hello”的请求。
<mvc:exclude-mapping><mvc:exclude-mapping> 为<mvc:interceptor> 的子标签,用来配置不需要被拦截器拦截的路径。
<bean><bean> 为<mvc:interceptor> 的子标签,用来定义一个指定了拦截路径的拦截器。

1. 通过 <bean> 子标签配置全局拦截器

在 Spring MVC 的配置文件中,通过 <mvc:interceptors> 标签及其子标签 <bean> ,将我们自定义的拦截器配置成了一个全局拦截器。该拦截器会对项目内所有的请求进行拦截,配置代码如下。

<!--配置拦截器-->
<mvc:interceptors>
    <bean class="com.cky.interceptor.MyInterceptor"></bean>
</mvc:interceptors>

2. 通过 <ref> 子标签配置全局拦截器

除了 <bean> 标签外,还可以在 <mvc:interceptors> 标签中通过子标签 <ref> 定义一个全局拦截器引用,对所有的请求进行拦截。

<!--将自定义的拦截器放到 ioc 容器中-->
<bean id="interceptor" class="com.cky.interceptor.MyInterceptor"></bean>
<!--配置拦截器-->
<mvc:interceptors>
    <!--通过 ref 配置全局拦截器-->
    <ref bean="interceptor"></ref>
</mvc:interceptors>

注意:<mvc:interceptors> 标签的 <ref> 子标签不能单独使用,它需要与 <bean> 标签(<mvc:interceptors> 标签内或<mvc:interceptors>标签外)或 @Component 等注解配合使用,以保证 <ref> 标签配置的拦截器是Spring IOC 容器中的组件。

3. 通过<mvc:interceptor>子标签对拦截路径进行配置

还可以在 Spring MVC 的配置文件中通过 <mvc:interceptors> 标签的子标签 <mvc:interceptor>,对拦截器拦截的请求路径进行配置,示例配置如下。

<!--配置拦截器-->
<mvc:interceptors>
    <!--拦截器 1-->
    <mvc:interceptor>
        <!--配置拦截器拦截的请求路径-->
        <mvc:mapping path="/**"/>
        <!--配置拦截器不需要拦截的请求路径-->
        <mvc:exclude-mapping path="/login"/>
        <mvc:exclude-mapping path="/"/>
        <!--定义在 <mvc:interceptors> 下,表示拦截器只对指定路径的请求进行拦截-->
        <bean class="com.cky.interceptor.MyInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

需要注意的是,在 <mvc:interceptor> 中,子元素必须按照上述代码的配置顺序进行编写,即 <mvc:mapping> → <mvc:exclude-mapping> → <bean> 的顺序,否则就会报错。其次,以上这三种配置拦截器的方式,我们可以根据自身的需求以任意的组合方式进行配置,以实现在 <mvc:interceptors> 标签中定义多个拦截器的目的。

拦截器的执行流程

 拦截器的执行流程如下图所示。

 

拦截器处理流程的步骤如下:

  1. 当请求的路径与拦截器拦截的路径相匹配时,程序会先执行拦截器类(MyInterceptor)的 preHandl() 方法。若该方法返回值为 true,则继续向下执行 Controller(控制器)中的方法,否则将不再向下执行;
  2. 控制器方法对请求进行处理;
  3. 调用拦截器的 postHandl() 方法,此时我们可以对请求域中的模型(Model)数据和视图做出进一步的修改;
  4. 通过 DispatcherServlet 的 render() 方法对视图进行渲染;
  5. 调用拦截器的 afterCompletion () 方法,完成资源清理、日志记录等工作。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/986336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot设置热部署

一、常见的三种方式&#xff1a; Springboot中常见的热部署方式有3种: 1.使用springloaded配置pom.xml文件&#xff0c;使用mvn spring-boot:run启动 2.使用springloaded本地加载启动&#xff0c;配置jvm参数 3.使用devtools工具包&#xff0c;操作简单&#xff0c;但是每次…

python开发基础篇1——后端操作K8s API方式

文章目录 一、基本了解1.1 操作k8s API1.2 基本使用 二、数据表格展示K8s常见资源2.1 Namespace2.2 Node2.3 PV2.4 Deployment2.5 DaemonSet2.6 StatefulSet2.7 Pod2.8 Service2.9 Ingress2.10 PVC2.11 ConfigMap2.12 Secret2.13 优化 一、基本了解 操作K8s资源api方式&#xf…

第11篇:ESP32vscode_platformio_idf框架helloworld点亮LED

第1篇:Arduino与ESP32开发板的安装方法 第2篇:ESP32 helloword第一个程序示范点亮板载LED 第3篇:vscode搭建esp32 arduino开发环境 第4篇:vscodeplatformio搭建esp32 arduino开发环境 ​​​​​​第5篇:doit_esp32_devkit_v1使用pmw呼吸灯实验 第6篇:ESP32连接无源喇叭播…

酷克数据推出AI开发工具箱HashML 加速企业级AI应用落地投产

近日&#xff0c;业界领先的国产企业级云数仓厂商酷克数据发布了下一代In-Database高级分析和数据科学工具箱HashML&#xff0c;在业内率先实现为企业提供随数仓部署一步到位、开箱即用的AI能力。 在数字经济时代&#xff0c;描述性分析已经非常成熟并被企业广泛采纳。然而&am…

vue3:3、项目目录和关键文件

关于vsvode的更改 <!-- 加上setup允许在script中直接编写组合式api --> <script setup> // 组件引入后直接用 import HelloWorld from ./components/HelloWorld.vue import TheWelcome from ./components/TheWelcome.vue</script><!-- 1、js放在最上面&am…

JDK源码剖析之PriorityQueue优先级队列

写在前面 版本信息&#xff1a; JDK1.8 PriorityQueue介绍 在数据结构中&#xff0c;队列分为FIFO、LIFO 两种模型&#xff0c;分别为先进先出&#xff0c;后进后出、先进后出&#xff0c;后进先出&#xff08;栈&#xff09; 而一切数据结构都是基于数组或者是链表实现。 在…

线上问诊:可视化展示

系列文章目录 线上问诊&#xff1a;业务数据采集 线上问诊&#xff1a;数仓数据同步 线上问诊&#xff1a;数仓开发(一) 线上问诊&#xff1a;数仓开发(二) 线上问诊&#xff1a;数仓开发(三) 线上问诊&#xff1a;可视化展示 文章目录 系列文章目录前言一、全流程调度1.生产新…

两两交换链表中节点

给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4] 输出&#xff1a;[2,1,4…

【python 多线程】初体验+单线程下载器+并行下载器

1.多线程初体验 主线程的id和进程的id是一个 查看进程pid下有多少个线程 ps -T -p pid(base) D:\code\python_project\python_coroutine>C:/ProgramData/Anaconda3/python.exe d:/code/python_project/python_coroutine/01demo.py threading.active_count1 i am producer…

vue手写提示组件弹窗

1、弹框展示 2、message组件 新建一个message.vue <template><div class"wrapper" v-if"isShow" :class"showContent ? fadein : fadeout">{{ text }}</div> </template> <script></script> <style s…

智能小车之跟随小车、避障小车原理和代码

目录 1. 红外壁障模块分析​编辑 2. 跟随小车的原理 3. 跟随小车开发和调试代码 4. 超声波模块介绍 5. 摇头测距小车开发和调试代码 1. 红外壁障模块分析 原理和循迹是一样的&#xff0c;循迹红外观朝下&#xff0c;跟随朝前 TCRT5000传感器的红外发射二极管不断发射红外…

使用半导体材料制作霍尔元件的优点

霍尔元件是一种基于霍尔效应的传感器&#xff0c;可以测量磁场强度和电流等物理量。霍尔效应是指&#xff0c;当电流通过一块导体时&#xff0c;如果该导体置于垂直于电流方向的磁场中&#xff0c;就会在导体两侧出现一定的电势差&#xff0c;这就是霍尔效应。霍尔元件可以利用…

亚马逊云科技与百川智能发起AI黑客松,共探医疗健康和游戏娱乐领域的前沿应用

8月31日&#xff0c;亚马逊云科技云创计划成员企业暨基础模型创业公司百川智能&#xff0c;率先通过了《生成式人工智能服务管理暂行办法》备案&#xff0c;即日起面向全社会开放服务。基础模型获准面向公众用户开放服务&#xff0c;意味着有机会基于大量真实用户的调用反馈建立…

Android使用Kotlin封装MMKVUtils

Android使用Kotlin封装MMKVUtils 1.简介&#xff1a; MMKV 是基于 mmap 内存映射的 key-value 组件&#xff0c;底层序列化/反序列化使用 protobuf 实现&#xff0c;性能高&#xff0c;稳定性强。从 2015 年中至今在微信上使用&#xff0c;其性能和稳定性经过了时间的验证。近…

【第二章 数据的表示和运算】2.3

IEEE规格化&#xff1a; 18&#xff08;阶码移码偏置值127&#xff0c;取值范围1-254&#xff0c;负值要补码取原码&#xff09;23&#xff08;隐1.原码&#xff09;

测试阶段之冒烟测试

冒烟测试 一般建议1-2个小时完成冒烟测试。 注意冒烟用例不是P1P2&#xff0c;而是其中的部分用例

yum安装mysql5.7散记

## 数据源安装 $ yum -y install wget $ wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm $ yum localinstall mysql57-community-release-el7-8.noarch.rpm $ yum repolist enabled | grep "mysql.*-community.*" $ yum install mysql-…

IDEA Properties 文件亂碼怎麼解決

1.FIle->Setting->Editor->File Encodings 修改Properties FIles 編碼顯示格式&#xff1a;UTF-8

一百七十二、Flume——Flume采集Kafka数据写入HDFS中(亲测有效、附截图)

一、目的 作为日志采集工具Flume&#xff0c;它在项目中最常见的就是采集Kafka中的数据然后写入HDFS或者HBase中&#xff0c;这里就是用flume采集Kafka的数据导入HDFS中 二、各工具版本 &#xff08;一&#xff09;Kafka kafka_2.13-3.0.0.tgz &#xff08;二&#xff09;…

Netty编程面试题

1.Netty 是什么&#xff1f; Netty是 一个异步事件驱动的网络应用程序框架&#xff0c;用于快速开发可维护的高性能协议服务器和客户端。Netty是基于nio的&#xff0c;它封装了jdk的nio&#xff0c;让我们使用起来更加方法灵活。 2.Netty 的特点是什么&#xff1f; 高并发&a…