Spring中的拦截器
这里写目录标题
- 基本概念
- HandlerInterceptor拦截器
- HandlerInterceptor讲解
- MethodInterceptor拦截器
- 二者的区别
基本概念
在web开发中,拦截器是经常用到的功能。它可以帮我们预先设置数据以及统计方法的执行效率等等。
Spring中拦截器主要分两种,一个是HandlerInterceptor,一个是MethodInterceptor。
HandlerInterceptor拦截器
HandlerInterceptor是SpringMVC项目中的拦截器,它拦截的目标是请求的地址,比MethodInterceptor先执行。其工作原理是当请求来时先进行预处理,如下:
通过HandlerInterceptor实现打印请求开始和结束的日志,代码如下:
引入相关依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
拦截器:
import lombok.extern.slf4j.Slf4j;
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;@Slf4j
@Component
public class EasyLogControllerInterceptor implements HandlerInterceptor {/*** 在controller调用之前执行*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {log.info(request.getRequestURI() + "开始执行");return true;}/*** 在controller调用中执行*/public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {}/*** 在controller调用后执行*/public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {log.info(request.getRequestURI() + "执行结束");}}
controller:
@GetMapping(value = "/test/user")
public String testUser() {log.info("test");return "string";
}
配置类:
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
@RequiredArgsConstructor
public class IntercepterConfig implements WebMvcConfigurer {private final EasyLogControllerInterceptor easyLogControllerInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//addPathPatterns用于添加拦截路径//excludePathPatterns用于添加不拦截的路径registry.addInterceptor(easyLogControllerInterceptor).addPathPatterns("/test/user");}//此方法用于配置静态资源路径@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/my/");}
}
输出结果:
2023-02-20 21:07:10.681 c.x.d.c.EasyLogControllerInterceptor : /test/user开始执行
2023-02-20 21:07:10.688 c.xhy.demo01.controller.HelloController : test
2023-02-20 21:07:10.714 c.x.d.c.EasyLogControllerInterceptor : /test/user执行结束
HandlerInterceptor讲解
实现一个HandlerInterceptor拦截器可以直接实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter类。这两种方法殊途同归,其实HandlerInterceptorAdapter也就是声明了HandlerInterceptor接口中所有方法的默认实现,而我们在继承他之后只需要重写必要的方法即可。
下面就是HandlerInterceptorAdapter的代码,可以看到一个方法只是默认返回true,另外两个是空方法:
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public abstract class HandlerInterceptorAdapter implements HandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {return true;}public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {}public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {}}
这三个方法都是干什么的,有什么作用,什么时候调用,不同的拦截器之间是怎样的调用顺序呢?
这还得参考一下DispatcherServlet的doDispatch方法:
代码有点长,但是它封装了SpringMVC处理请求的整个过程。首先根据请求找到对应的HandlerExecutionChain,它包含了处理请求的handler和所有的HandlerInterceptor拦截器;然后在调用hander之前分别调用每个HandlerInterceptor拦截器的preHandle方法,若有一个拦截器返回false,则会调用triggerAfterCompletion方法,并且立即返回不再往下执行;若所有的拦截器全部返回true并且没有出现异常,则调用handler返回ModelAndView对象;再然后分别调用每个拦截器的postHandle方法;最后即使是之前的步骤抛出了异常,也会执行triggerAfterCompletion方法。
MethodInterceptor拦截器
MethodInterceptor是AOP项目中的拦截器,它拦截的目标是方法,即使不是controller中的方法
二者的区别
上面的两种拦截器都能起到拦截的效果,但是他们拦截的目标不一样,实现的机制不同,所以有的时候适用不同的场景。
HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适。当你需要统计请求的响应时间时,MethodInterceptor将不太容易做到,因为它可能跨越很多方法或者只涉及到已经定义好的方法中一部分代码。MethodInterceptor利用的是AOP的实现机制,在本文中只说明了使用方式,关于原理和机制方面介绍的比较少,因为要说清楚这些需要讲出AOP的相当一部分内容。在对一些普通的方法上的拦截HandlerInterceptoer就无能为力了,这时候只能利用AOP的MethodInterceptor。
另外,还有一个跟拦截器类似的东西----Filter。Filter是Servlet规范规定的,不属于Spring框架,也是用于请求的拦截。但是它适合更粗粒度的拦截,在请求前后做一些编解码处理、日志记录等。而拦截器则可以提供更细粒度的,更加灵活的,针对某些请求、某些方法的组合的解决方案。
另外,用过人人网的ROSE框架的人都会非常喜欢它的拦截器功能。因为它实现了全注解的方式,只要在类的名字上加上拦截器的注解即表示这是一个拦截器。而使用这个拦截器的方法或者controller也只需在方法或controller的上面加上这个拦截器的注解。其实这是一个关注点的转变,spring的切面控制在配置文件中,配置文件关注哪些地方需要拦截。而在ROSE中,则是在需要拦截的地方关注我要被谁拦截。
相关文章:

Spring中的拦截器
这里写目录标题基本概念HandlerInterceptor拦截器HandlerInterceptor讲解MethodInterceptor拦截器二者的区别基本概念 在web开发中,拦截器是经常用到的功能。它可以帮我们预先设置数据以及统计方法的执行效率等等。 Spring中拦截器主要分两种,一个是Han…...
【Linux操作系统】【综合实验四 Linux的编译环境及线程编程】
文章目录一、实验目的二、实验要求三、实验内容四、实验报告要求一、实验目的 要求熟悉Linux环境中的程序编译、调试与项目管理过程并能实现具体操作;熟练使用基础函数库中与线程库中的管理函数,实现用户线程编程过程,并深入了解Linux的线程…...
Switch 如何使用NSCB 转换XCI NSP NSZ教程
很多小白经常碰到Switch游戏文件格式和预期不符的情况,比如碰到nsz自己不会安装(安装NSZ格式文件教程);或者是碰到xci格式的,想转换为nsp;抑或想将nsz格式文件还原回nsp格式。本文对此提供了解决方案。 文中…...

JVM12 字节码指令集
1. 概述 2. 加载与存储指令 2.1. 局部变量压栈指令 iload 从局部变量中装载int类型值 lload 从局部变量中装载long类型值 fload 从局部变量中装载float类型值 dload 从局部变量中装载double类型值 aload 从局部变量中装载引用类型值(refernce) iload_0 从…...
centos之python安装与多版本python之间的共存
一、背景 随着python版本迭代加快,有写python模块再低版本无法运行,此时需要我们在进行安装一个python版本 例如:uvloop 在python3.7上运行;python 3.6官方不再维护与更新 有些模块或不支持较低版本、有些模块支持较高版本python…...
SpringBoot学习笔记(一)
Idea中隐藏指定文件或指定类型文件 setting->File Types->Ignored Files and Folders输入要隐藏的文件名,支持*号通配符回车确认添加 SpringBoot概述 parent 小结: 开发SpringBoot程序要继承spring-boot-starter-parentspring-boot-starter-pa…...

美国原装KEYSIGHT E4981A(安捷伦) E4981A电容计
KEYSIGHT E4981A(安捷伦) Keysight E4981A(安捷伦)电容计为生产线中的陶瓷电容器测试提供了高速、可靠的测量。E4981A 实现了电容从小到大的测量能力,测量准确。Agilent E4981A 电容计有助于提高测试吞吐量࿰…...

K8S的基础概念
目录 一、k8s概述 1、k8s简介 1.1 k8s的作用 1.2 k8s的由来 1.3 k8s的含义 1.4 k8s的官网 1.5 GitHub 2、为什么要用 K8S? 2.1 K8s的目标 2.2 K8s解决了裸跑Docker 的若干痛点: 2.3 K8s的主要功能 3、K8s的特性 二、Kubernetes 集群架构与组件 1、工作流程 2、…...

【数据结构】——环形队列
文章目录一.环形队列的定义及其特点二.使用数组来实现环形队列1.创建一个队列2.初始化队列3. 判断环形队列是否为空4.判断环形队列是否已满5. 向循环队列插入元素,插入成功返回真6.删除环形链表的数据7. 取队头元素8.取队尾元素8.释放空间总结一.环形队列的定义及其…...

windows 安装Qt
下载 下载地址https://download.qt.io/,此文已5.7.0为例子。 根据图片依次选择即可。 安装 安装过程参考另一篇文章Ubuntu 安装 Qt5.7.0即可 配置环境变量 ps:我就是之前没配置环境变量,直接使用创建项目,项目源码直接运行是…...

spring cloud gateway集成sentinel并扩展支持restful api进行url粒度的流量治理
sentinel集成网关支持restful接口进行url粒度的流量治理前言使用网关进行总体流量治理(sentinel版本:1.8.6)1、cloud gateway添加依赖:2、sentinel配置3、网关类型项目配置4、通过zk事件监听刷新上报api分组信息1、非网关项目上报api分组信息…...

wafw00f工具
wafw00f Web应用程序防火墙指纹识别工具 github地址:https://github.com/EnableSecurity/wafw00f 安装环境:python3环境 —>使用 pip install wafw00f 进行安装 安装成功后目录:python安装目录中的Lib\site-packages\wafw00f 本机为&a…...

论文阅读笔记-DiffusionInst: Diffusion Model for Instance Segmentation
文章目录DiffusionInst: Diffusion Model for Instance Segmentation摘要介绍任务介绍实例分割的几种方法想法来源贡献方法整体结构Mask RepresentationDiffusionInst组成TrainingInference不足之处感悟DiffusionInst: Diffusion Model for Instance Segmentation 代码&#x…...

解决CondaUpgradeError网上的方法都不奏效(回退版本、upgrade/update都不行)的问题和CondaValueError
问题描述 Executing transaction: failed ERROR conda.core.link:_execute(502): An error occurred while installing package ‘conda-forge::certifi-2022.9.24-pyhd8ed1ab_0’. CondaUpgradeError: This environment has previously been operated on by a conda version…...

基于某业务单登陆场景并发测试实战
文章目录1 测试目的2 测试目标和测试对象3 名词解释4 测试说明5 测试环境和工具5.1 测试工具5.2 测试环境5.3 人力计划6 测试用例6.1 方案设计6.2 接口地址6.3 接口参数6.3.1 header参数6.3.2 请求参数7 脚本设计8 监控数据8.1 虚拟用户并发情况8.2 事务响应时间8.3 每秒点击次…...

JVM内存模型
程序计数器 多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源。因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令。线程私有的内存区域。如果执行的是JAVA方法,计数器记录正…...

三、NetworkX工具包实战3——特征工程【CS224W】(Datawhale组队学习)
开源内容:https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频:https://space.bilibili.com/1900783/channel/collectiondetail?sid915098 斯坦福官方课程主页:https://web.stanford.edu/class/cs224w NetworkX…...

分布式之Raft共识算法分析
写在前面 在分布式之Paxos共识算法分析 一文中我们分析了paxos算法,知道了其包括basic paxos和multi paxos,并了解了multi paxos只是一种分布式共识算法的思想,而非具体算法,但可根据其设计具体的算法,本文就一起来看…...
数据库——范式
目录 一、概念 二、各范式 第一范式 第二范式 第三范式 BC范式 第四范式 第五范式(略) 一、概念 基本概念 关系:通常一个关系对应一张表;元组:一行;属性:一列;码࿱…...
Geospatial Data Science(2):Geospatial Data in Python
Geospatial Data Science(2):Geospatial Data in Python PART 1: 检查数据 1.1 Imports import geopandas as gpd # for geospatial data handling import osmnx # for handling data from OpenStreetMap (osm) with the help of networkX (nx) import contextily as cx # f…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...