SpringMVC拦截器深度解析与实战

引言
Spring MVC作为Spring框架的核心模块之一,主要用于构建Web应用程序和RESTful服务。在Spring MVC中,拦截器(Interceptor)是一种强大的机制,它允许开发者在请求处理流程的特定点插入自定义代码,实现诸如权限验证、日志记录、请求预处理等功能。本文将深入解析Spring MVC拦截器的概念、工作原理、使用场景以及实现方式,并通过代码示例进行演示。
拦截器概念
什么是拦截器
拦截器(Interceptor)是Spring MVC中用于动态拦截请求处理流程的一种机制。在请求到达控制器(Controller)之前或响应返回给客户端之后,拦截器可以对请求和响应进行预处理和后处理。拦截器是AOP(面向切面编程)思想在Spring MVC中的具体实现之一。
拦截器与过滤器的区别
拦截器和过滤器(Filter)在Web开发中经常被提及,但它们之间存在明显的区别:
- 作用范围:过滤器可以拦截几乎所有的请求,包括静态资源,而拦截器只能拦截到控制器(Controller)中的请求方法。
- 依赖关系:过滤器依赖于Servlet容器,而拦截器不依赖于Web容器,是Spring MVC的组件。
- 灵活性:拦截器可以方便地访问Spring容器中的bean,而过滤器则相对困难。
拦截器的作用
拦截器主要用于在请求处理流程中的特定点执行自定义逻辑,其作用包括但不限于:
- 权限验证:检查用户是否拥有访问某个资源的权限。
- 日志记录:记录请求和响应的详细信息,便于问题追踪。
- 请求预处理:在请求到达控制器之前对请求数据进行修改或补充。
- 响应后处理:在响应返回给客户端之前对响应数据进行修改或添加额外的头信息。
拦截器的实现
定义拦截器
在Spring MVC中,定义一个拦截器需要实现HandlerInterceptor接口或继承HandlerInterceptorAdapter类。HandlerInterceptor接口包含三个方法:
- preHandle(HttpServletRequest request, HttpServletResponse response, Object handler): 在请求处理之前进行调用(Controller方法调用之前)。
- postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView): 请求处理之后进行调用,但在视图被渲染之前(Controller方法调用之后,DispatcherServlet渲染视图之前)。
- afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex): 在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图执行之后。
示例代码
以下是一个简单的拦截器实现示例:
java
| package com.example.interceptor; | |
| 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 MyInterceptor implements HandlerInterceptor { | |
| @Override | |
| public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |
| System.out.println("在Controller方法执行前执行"); | |
| // 可以进行权限验证等操作,如果验证失败,返回false以中断后续流程 | |
| return true; | |
| } | |
| @Override | |
| public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { | |
| System.out.println("在Controller方法执行后,视图渲染前执行"); | |
| // 可以对ModelAndView进行修改 | |
| if (modelAndView != null) { | |
| modelAndView.addObject("customAttribute", "自定义属性值"); | |
| } | |
| } | |
| @Override | |
| public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { | |
| System.out.println("在所有请求处理完成后执行"); | |
| // 进行资源清理等操作 | |
| } | |
| } |
配置拦截器
定义拦截器后,需要在Spring MVC配置中注册该拦截器,并指定其拦截的路径。在Spring Boot项目中,通常通过实现WebMvcConfigurer接口并重写addInterceptors方法来完成:
当然,下面是继续完成WebConfig类的实现,包括如何将自定义的拦截器添加到Spring MVC的拦截器链中,并指定其拦截的路径。
完成WebConfig配置
java
| package com.example.config; | |
| import com.example.interceptor.MyInterceptor; | |
| import org.springframework.beans.factory.annotation.Autowired; | |
| import org.springframework.context.annotation.Configuration; | |
| import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | |
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |
| @Configuration | |
| public class WebConfig implements WebMvcConfigurer { | |
| @Autowired | |
| private MyInterceptor myInterceptor; | |
| @Override | |
| public void addInterceptors(InterceptorRegistry registry) { | |
| // 添加拦截器,并设置拦截路径和排除路径 | |
| registry.addInterceptor(myInterceptor) | |
| .addPathPatterns("/**") // 拦截所有请求 | |
| .excludePathPatterns("/static/**", "/error"); // 排除静态资源和错误页面的拦截 | |
| } | |
| } |
在这个配置中,addInterceptors方法通过InterceptorRegistry注册了MyInterceptor拦截器,并使用addPathPatterns方法指定了拦截器需要拦截的路径模式(在这个例子中是所有请求,即/**)。同时,使用excludePathPatterns方法排除了静态资源(如/static/**)和错误页面(/error)的拦截,这是为了避免对不需要拦截的资源进行不必要的处理。
拦截器的使用场景
- 权限控制:在preHandle方法中检查用户是否拥有访问某个资源的权限,如果没有则直接返回错误响应或重定向到登录页面。
- 日志记录:在preHandle或afterCompletion方法中记录请求和响应的详细信息,包括请求参数、IP地址、处理时间等,有助于问题的追踪和系统的监控。
- 请求预处理:在preHandle方法中修改请求参数、设置请求头或执行其他预处理操作。
- 响应后处理:在postHandle方法中修改响应内容或状态码,或在afterCompletion方法中执行一些清理工作。
- 性能监控:在preHandle和afterCompletion方法中记录时间戳,计算请求处理时间,从而监控系统的性能。
注意事项
- 拦截器的执行顺序:在Spring MVC中,拦截器的执行顺序是通过它们在InterceptorRegistry中的注册顺序来决定的。如果需要改变执行顺序,可以调整注册的顺序。
- 拦截器链的传递性:在preHandle方法中返回false将中断拦截器链的后续执行,并直接跳到afterCompletion方法(如果存在)。如果返回true,则继续执行下一个拦截器的preHandle方法或最终执行控制器的目标方法。
- 拦截器的错误处理:在拦截器链中的任何位置发生异常时,都会依次执行已调用拦截器的afterCompletion方法(如果有的话),即使异常发生在preHandle方法中也是如此。
通过上述解析和示例,你应该对Spring MVC中的拦截器有了更深入的理解,并能够在实际项目中灵活运用它们来增强Web应用的功能和性能。
相关文章:
SpringMVC拦截器深度解析与实战
引言 Spring MVC作为Spring框架的核心模块之一,主要用于构建Web应用程序和RESTful服务。在Spring MVC中,拦截器(Interceptor)是一种强大的机制,它允许开发者在请求处理流程的特定点插入自定义代码,实现诸如…...
直线上最多的点数
优质博文:IT-BLOG-CN 题目 给你一个数组points,其中points[i] [xi, yi]表示X-Y平面上的一个点。求最多有多少个点在同一条直线上。 示例 1: 输入:points [[1,1],[2,2],[3,3]] 输出:3 示例 2: 输入&am…...
经济管理专业数据库介绍
本文介绍了四个经济管理专业数据库:国研网全文数据库、EPS数据平台、中经网、Emerald全文期刊库(管理学)。 一、国研网全文数据库 国研网是国务院发展研究中心主管、北京国研网信息有限公司承办的大型经济类专业网站。国研网教育版”是国研…...
【C++ Primer Plus习题】11.1
问题: 解答: main.cpp #include <iostream> #include <fstream> #include "Vector.h" #include <time.h> using namespace std; using namespace VECTOR;int main() {ofstream fout;fout.open("randwalk.txt");srand(time(0));double d…...
[数据库][oracle]ORACLE EXP/IMP的使用详解
导入/导出是ORACLE幸存的最古老的两个命令行工具,其实我从来不认为Exp/Imp是一种好的备份方式,正确的说法是Exp/Imp只能是一个好的转储工具,特别是在小型数据库的转储,表空间的迁移,表的抽取,检测逻辑和物理…...
中国各银行流动性比例数据(2000-2022年)
介绍中国银行业2000年至2022年间的流动性比例数据,涵盖500多家银行,包括城市商业银行、城镇银行、大型商业银行、股份制银行、民营银行、农村合作银行、农村商业银行、农村信用社等。这些数据对于理解中国银行业的流动性状况至关重要,有助于投…...
MACOS安装配置前端开发环境
官网下载安装Mac版本的谷歌浏览器以及VS code代码编辑器,还有在App Store中直接安装Xcode(里面自带git); node.js版本管理器nvm的下载安装如下: 参考B站:https://www.bilibili.com/video/BV1M54y1N7fx/?sp…...
Docker 配置国内镜像源
由于 GFW 的原因,在下载镜像的时候,经常会出现下载失败的情况,此时就可以使用国内的镜像源。 什么是镜像源:简单来说就是某个组织(学校、公司、甚至是个人)先通过某种手段将国外的镜像下载下来,…...
AI模块在人工智能中扮演着什么样的角色
AI模块在人工智能(AI)中扮演着核心和关键的角色。它们是构成AI系统的基础单元,负责实现AI系统的各种智能功能。以下是AI模块在人工智能中扮演的具体角色: 功能实现的核心:AI模块集成了实现特定智能功能所需的算法、数据…...
VM Workstation虚拟机AlmaLinux 9.4操作系统安装(桌面版安装详细教程)(宝塔面板的安装),填补CentOS终止支持维护的空白
目录 AlmaLinux介绍 AlmaLinux操作系统的安装 1、下载镜像文件 2、新建虚拟机 (1)点击创建新的虚拟机 (2)打开虚拟机向导后,选择“自定义”安装,然后点击“下一步” (3)选择虚…...
【学习笔记】卫星通信NTN 3GPP标准化进展分析(三)- 3GPP Release17 内容
一、引言: 本文来自3GPP Joern Krause, 3GPP MCC (May 14,2024) Non-Terrestrial Networks (NTN) (3gpp.org) 本文总结了NTN标准化进程以及后续的研究计划,是学习NTN协议的入门。 【学习笔记】卫星通信NTN 3GPP标准化进展分析(一ÿ…...
【SQL】常见语句合集
SQL常见语句合集 一. 新建表1.1 语句1.2 结果 二. 新增数据2.1 语句2.2 结果 三. 新增字段列3.1 语句3.2 结果3.3 扩展 四. 更新指定数据4.1 语句4.2 结果 五. 更新指定列5.1 语句(长度) 六. 删除字段列6.1 语句 七. 删除指定数据7.1 语句 八. 查询 一. …...
Cozer必备!一站式解锁扣子全网最全插件集锦(三)
俗话说,工欲善其事必先利其器! 用过Coze的朋友都知道,插件在Coze里的重要性。插件库就相当于武器库,一个好的插件,就相当于一件趁手的兵器,可以让你事半功倍! 程哥精心整理了Coze最常用和好用…...
1-2宿主环境
什么是宿主环境 指的是程序运行所必须的依赖环境。Android系统和ios系统是两个不同的宿主环境,安卓版的app是不能在ios系统上运行的。 小程序的宿主环境 🍕🍕🍕 -手机微信是小程序的宿主环境 通信的主体 🍔&…...
Java进阶13讲__第九讲
Stream流 1. 案例初体验 package cn.hdc.oop9.stream.using;import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream;public class t1 {public static void main(String[] args) {LinkedList<String&g…...
上海市计算机学会竞赛平台2024年8月月赛丙组等差数列的素性
题目描述 给定三个整数 nn,aa 与 dd,表示一个项数为 nn 的等差数列,首项为 aa,公差为 dd。 请统计,从这个等差数列中有多少数字是素数 输入格式 三个整数: nn,aa 与 dd 输出格式 单个整数…...
VR虚拟展厅的应用场景有哪些?
虚拟展厅作为一种利用虚拟现实技术构建的三维展示空间,其应用场景广泛且多样。视创云展为企业虚拟展厅搭建提供技术支持。以下是一些主要的应用场景: 1. 博物馆和艺术展览 文物保护与展示: 在博物馆中,为了保护珍贵的文物和艺术…...
Go 语言版本管理——Goenv
Go 语言版本管理——Goenv 命令安装 goenv安装和切换 Go 版本 goenv 是一个专门管理 Go 语言版本的工具。 命令 安装 goenv github-goenv git clone https://github.com/go-nv/goenv.git ~/.goenv echo export GOENV_ROOT"$HOME/.goenv" >> ~/.bash_profile…...
C#中的各种画刷, PathGradientBrush、线性渐变(LinearGradientBrush)和径向渐变的区别
在C#中,画刷(Brush)是用来填充图形(如形状或文本)内部区域的对象。在.NET框架中,画刷是System.Drawing命名空间的一部分,通常用于GDI绘图操作。以下是一些常用的画刷类型: SolidBru…...
如何在Mac中修改pip的镜像源
一. 修改步骤 进入命令行 进入到用户根目录 cd ~/在用户根目录下创建 .pip 文件夹 mkdir .pip进入到 ~/.pip 文件夹内 cd ~/.pip创建 pip.conf 文件 vim pip.conf在 pip.conf 文件中添加清华大学的镜像源,如下: [global] index-urlhttps://pypi.tuna.ts…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
