Spring Boot统一功能处理(一)
本篇主要介绍Spring Boot的统一功能处理中的拦截器。
目录
一、拦截器的基本使用
二、拦截器实操
三、浅尝源码
初始化DispatcherServerlet
处理请求(doDispatch)
四、适配器模式
一、拦截器的基本使用
在一般的学校或者社区门口,通常会安排几个保安大爷来进行身份验证,只有身份符合要求的人才会被放行,否则则会被大爷拦住,而拦截器就像我们程序的保安大爷,只有通过我们自己定义的拦截规则,请求才能被放行到目标接口上。
下面我们来看看如何在Spring Boot中使用拦截器
在项目中设置拦截,我们需要先自己定义一些拦截器,里面包含一些具体的拦截规则,定义拦截器的代码如下:
(1)首先创建一个拦截类,通常以“Interceptor”作为类名的后半部分,这里我们定义一个LoginInterceptor类,意为与登录相关的拦截器,然后让该类实现一个HandlerInterceptor接口,具体如下:
@Component
public class LoginInterceptor implements HandlerInterceptor {}
(2)重写三个方法:
@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
其中preHandle为在目标方法执行前要执行的方法,其返回值如果为true,则会被放行去执行目标方法,为false则拦截,我们可以在这个方法里根据需求定义拦截规则。postHandle为目标方法执行后要执行的方法。afterCompletion为最后视图渲染完后最后执行的方法(由于现在都是前后端分离了,后端一般不处理视图,因此这个方法不需要过多了解)。
定义好拦截器后我们还需要配置拦截器,具体配置流程如下:
(1)创建配置类(一般以Config结尾,这里以为WebConfig),实现WebMvcConfigurer接口:
public class WebConfig implements WebMvcConfigurer {
}
(2)然后重写addInterceptor方法
@Overridepublic void addInterceptors(InterceptorRegistry registry) {}
(3)然后我们在里面添加我们需要配置的拦截器,具体如下:
这里我们可以通过@Autowired注入一个LoginInterceptor对象,也可以直接在参数里new一个,只要是传入一个实现前面的HandlerInterceptor接口的类的对象即可。
(4)然后在配置我们需要拦截的路径(即请求url中ip地址端口号的后面的部分):
这里的”/**"表示任意路径,例如“/user/book、/user”等,另外还有“/*"他只能表示一级路径,例如:
”/user,/book"等。
(4)由于通常我们并不需要所有路径都进行拦截(例如登录请求),因此我们还需要排除一些路径,让这些路径不被拦截,具体如下:
(5)最后我们还需要把这个类放到Spring容器里,由于这里与配置相关,所有使用@Configuration。
二、拦截器实操
接下来我们来实操一下。首先我们创建一个Controller类,在里面定义一个login方法(这里只是简单测试一下,不进行密码校验,只是给用户设置一个登录状态而已):
然后再添加几个测试方法:
然后我们再来定义一下拦截器,再preHandle方法中设置一下拦截规则,只有处于登录状态才能放行 ,并在另外两个方法中打印日志来进行观察:
然后在注册(配置)一下拦截器(不拦截login方法,其他全部拦截) :
最后我们通过postMan构造请求来访问一下这些方法.
先访问一下test01
可以发现返回的响应为空,也就是说请求被拦截器拦截到了。
然后我们再来访问一下login
可以发现响应有数据了,但由于我们请求中没有传值,导致接口中的两个参数为空,所以返回了false。接下来我们补上这两个值再访问一下
可以发现响应中返回true了,同时这也意味着我们现在已经给用户设置成登录状态了,此时我们再来访问test01
可以发现响应已经有数据了。这也就意味着这个请求已经被拦截器放行了。
最后我们再来看一下 控制台的日志:
可以发现,拦截器是严格按照顺序执行相关方法的 ,如果请求被拦截了,则只会执行postHandle方法就返回了,如果请求被放行则会按顺序执行完拦截器中的三个方法。并且对于配置中没有涉及到的路径,和被排除的路径,则根本不会进入到拦截器。
三、浅尝源码
接下来,我们来浅浅阅读一下与拦截器相关的部分源码。
初始化DispatcherServerlet
仔细观察日志可以发现,当我们的服务器接收到第一个来自前端的请求时,会初始化一个dispatcherServerlet类。
它的初始化方法为init(),具体实现是在其父类HttpServerletBean中实现的
init方法首先创建了一个PropertyValues类,这个类我并不知道是干嘛的,但根据其名称可以大体猜出来应该是去读一些配置,并且下面的if语句 判断这个对象是否为空,不为空才去执行相关逻辑,因此可以推测出if语句里应该是去根据读到的配置去进行一些设置。在init方法最后执行了一个initServerletBean方法,,我们来具体看一下这个方法,
转到定义可以发现HttpServerletBean中并未实现这个方法,接下来我们去其子类看一下
可以发现其子类FrameworkServerlet重写了这个方法,并具体进行了实现。仔细观察可以发现这个方法主要是在打印日志,日志的内容就是我们在前面控制台所看到的
并且 这里还进行了计时,并打印在了日志里。除去日志的部分可以发现这个方法就只剩下try-catch中的内容了:
接下来我们继续进入到其中的initWebAppliactionContext ()来看一下,
根据名字可以发现这个方法应该是用来 初始化WebApplicationContext的,并且通过代码大致可以发现这个方法会先去从类的成员属性中获取WebAppliactionContext,如果成员属性不为空,则会直接用成员属性的,如果为空,则调用findWebApplication去寻找一个并使用,如果没找到,则去创建一个。执行完上面第一个红框里的内容后,wac应该是已经不再为空了的,接下来调用onRefresh方法,可以发现这里加了锁来防止线程安全问题。接下来我们进到onRefresh方法来看一下:
可以发现FrameWorkServerlet中并未进行实现,我们再进到其子类看一下:
可以发现子类进行了实现,并且此时这个子类就是我们要初始化的DispatchServerlet。然后我们再看看这个方法里使用的initStrategies()方法:
通过方法名称可以发现这个方法是在进行一些初始化,然后再通过具体代码可以发现这个方法初始化了九个组件,这些组件就是Spring的九大组件,其名称如下:
- MultipartResolver:文件上传解析器
- LocaleResolver:区域解析器
- ThemeResolver:主题解析器
- HandlerMappings:处理器映射器
- HandlerAdapters:处理器适配器
- HandlerExceptionResolvers:异常处理器解析器
- RequestToviewNameTranslator:视图名称转换器
- ViewResolvers:视图解析器
- FlashMapManager:FlashMap管理器
初始化这些组件后,DispatchServerlet就初始化完了。
处理请求(doDispatch)
初始化完成后,DispatchServerlet就能进行请求的处理了,处理请求,主要通过DispatchServerlet类的doDispatch方法来对请求调度给Controller来执行,下面我们来详细看一下这个方法:
首先它会去获取一个与请求对应的处理器,然后再根据处理器去获取一个能够使用的适配器
然后再根据适配器来顺序执行拦截器的相关方法以及目标方法 然后处理视图,并执行最后的afterCompletion方法
四、适配器模式
在前面浅尝源码时,提到了适配器这个概念,适配器使用到了一种设计模式 --- 适配器模式。适配器模式能将一个类的接口,转换成符合客户期待的接口,从而使原本并不能兼容使用的接口也能使用了。简单来说,就是有一个接口,由于兼容问题并不能直接使用,需要在中间加上一个适配器才能够使用这个接口。例如我们生活中的转接头,当我们的手机是Type_c的充电口,而我们却只有苹果的数据线时,这根苹果的数据线自然是冲不了我们的手机的,此时就需要一个转接头了,通过转接头,我们就可以给手机充电了。此处转接头就相当于我们的的适配器,而转接头的设计就相当于是是适配器模式这种设计思想
可能有人会说为什么 不在一开始就设计成兼容的接口呢,这样就没必要大费周章弄一个适配器了,这样固然好,但人并不是万能的,总会有我们意想不到的情况出现,面面俱到几乎是不可能的,就像使用Type-c接口的手机厂商肯定不会想到有人会用苹果的数据线来充电,但既然这个需求是存在的,也就不能不去实现了,重新设计的话,成本又太高,因此,就只能使用适配器这一无奈之举了。
相关文章:
Spring Boot统一功能处理(一)
本篇主要介绍Spring Boot的统一功能处理中的拦截器。 目录 一、拦截器的基本使用 二、拦截器实操 三、浅尝源码 初始化DispatcherServerlet 处理请求(doDispatch) 四、适配器模式 一、拦截器的基本使用 在一般的学校或者社区门口,通常会安排几个…...
我与C++的爱恋:类与对象(二)
🔥个人主页:guoguoqiang. 🔥专栏:我与C的爱恋 本篇着重介绍构造函数和析构函数,剩余内容在下篇解答。 一、类的默认成员函数 如果一个类中什么成员都没有,简称为空类。 任何类在什么都不写时…...
BERT入门:理解自然语言处理中的基本概念
1. 自然语言处理简介 自然语言处理(Natural Language Processing,NLP)是人工智能领域的重要分支,涉及计算机与人类自然语言之间的相互作用。NLP 的应用已经深入到我们日常生活中的方方面面,如智能助理、机器翻译、舆情…...
Discoverydevice.java和activity_discoverydevice.xml
一、Discoverydevice.java public class Discoverydevice extends AppCompatActivity {private DeviceAdapter mAdapter2;private final List<DeviceClass> mbondDeviceList new ArrayList<>();//搜索到的所有已绑定设备保存为列表private final List<Devic…...
华为OD机试 - 最多颜色的车辆(Java JS Python C C++)
须知 哈喽,本题库完全免费,收费是为了防止被爬,大家订阅专栏后可以私信联系退款。感谢支持 文章目录 须知题目描述输入描述输出描述解析代码题目描述 在一个狭小的路口,每秒只能通过一辆车,假设车辆的颜色只有 3 种,找出 N 秒内经过的最多颜色的车辆数量。 三种颜色编…...
【无人机/平衡车/机器人】详解STM32+MPU6050姿态解算—卡尔曼滤波+四元数法+互补滤波——附3个算法源码
效果: MPU6050姿态解算-卡尔曼滤波+四元数+互补滤波 目录 基础知识详解 欧拉角...
NzN的C++之路--构造函数与析构函数
如果一个类中既没有成员变量也没有成员函数,这个类简称为空类。空类中其实并不是什么都没有,任何类在什么都不写时,编译器会自动生成6个默认成员函数。那今天我们就来学习一下其中两个默认成员函数:构造函数与析构函数。先三连后看…...
【算法刷题day24】Leetcode:216. 组合总和 III、17. 电话号码的字母组合
文章目录 Leetcode 216. 组合总和 III解题思路代码总结 Leetcode 17. 电话号码的字母组合解题思路代码总结 草稿图网站 java的Deque Leetcode 216. 组合总和 III 题目:216. 组合总和 III 解析:代码随想录解析 解题思路 回溯三部曲:确定递归…...
一体化泵站的生产制造流程怎样
诸城市鑫淼环保小编带大家了解一下一体化泵站的生产制造流程怎样 综合泵站和传统式混泥土泵站的一大差别是,离去制造厂前,能够开展全部机械设备设备的生产加工及零部件加工,随后运送到建筑项目当场开展安裝。这类经营方式缩短了开发周期&…...
【1】C++设计模式之【单例模式】
单例模式在C中的实现方式有以下几种: 懒汉式(线程不安全)饿汉式(线程安全)双检锁/双重校验锁(DCL,线程安全)静态局部变量(线程安全)C11版本(线程…...
软件设计模式之解释器模式
一、引言 在软件设计中,我们经常遇到需要“解释”和执行某种特定语法或语言的情况。这时,解释器模式就派上了用场。解释器模式(Interpreter Pattern)是一种行为设计模式,它提供了一种解释语言的语法并定义一个句子如何…...
java Web课程管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc
一、源码特点 JSP 课程管理系统是一套完善的web设计系统,对理解JSP java 编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发,数据库为Mysql5.0,使用ja…...
Electron 桌面端应用的使用 ---前端开发
Electron是什么? Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。 入门…...
【SpringBoot:详解Bean装配】
🏡Java码农探花: 🔥 推荐专栏:<springboot学习> 🛸学无止境,不骄不躁,知行合一 文章目录 前言一、IoC容器的简介BeanFactory接口源码二、Bean装配扫描装配探索启动类条件装配自定义Bean总…...
前端如何将接口返回的码值转成对应的中文展示呢?
后端接口只返回码值,那前端如何将码值转成对应的中文展示呢? 项目中后端接口都是将码值返给前端,前端通过公共获取码值的接口然后将其对应转码 以下是举例操作: created() {//这是公共接口的码值表let oneType [{value: 01,content: 一类,},{value: 02,content: 二类,},];//…...
智慧公厕中的大数据、云计算和物联网技术引领未来公厕管理革命
现代社会对于公共卫生和环境保护的要求越来越高,智慧公厕作为城市基础设施建设的重要组成部分,正引领着公厕管理的革命。随着科技的不断进步,大数据、云计算和物联网技术的应用为智慧公厕带来了全新的可能性,(ZonTree中…...
Excel与项目管理软件比较?哪个是项目组合管理的最佳选择?
在定义和管理每个正在进行的项目的资源、任务、收益、风险和优先级时,项目组合管理已成为公司的战略要素。为了实现高效的项目组合管理,PMO 经理需要评估Excel 是否满足他们管理项目组合的需求,或者是否应该尝试不同的解决方案,例…...
过程控制风格的软件架构设计概念及其实际应用
摘要 过程控制风格的软件架构设计强调程序的流程控制逻辑和组件之间的交互方式,旨在提升系统的响应性、扩展性和可维护性。这种架构风格在需要严格的操作序列和流程控制的应用中尤为重要,例如在嵌入式系统、实时系统和复杂的业务流程管理中。本文将介绍…...
WPF 编辑器模式中隐藏/显示该元素
XAML中引用:xmlns:d"http://schemas.microsoft.com/expression/blend/2008" 在所需要的控件中加上d:Visibility"Visible"属性 d:Visibility属性有3个值,可以根据需要进行设置 转自:在Visual Studio设计器中隐藏WPF元素…...
分布式事务 - 个人笔记 @by_TWJ
目录 1. 传统事务1.1. 事务特征1.2. 事务隔离级别1.2.1. 表格展示1.2.2. oracle和mysql可支持的事务隔离级别 2. 分布式事务2.1. CAP指标2.2. BASE理论2.3. 7种常见的分布式事务方案2.3.1. 2PC2.3.2. 3PC2.3.3. TCC2.3.3.1. TCC的注意事项:2.3.3.2. TCC方案的优缺点…...
解决前端笔记本电脑屏幕显示缩放比例125%、150%对页面大小的影响问题--数据可视化大屏
近期在工作中遇到一个问题,记录一下,在项目上线之后,遇到一个问题,即缩放到90%时,页面字体比默认的100%字体大,一开始毫无头绪,经过一番的Google...Google...Google....,终于找到了解…...
【PG-1】PostgreSQL体系结构概述
1. PostgreSQL体系结构概述 代码结构 其中,backend是后端核心代码,包括右边的几个dir: access:处理数据访问方法和索引的代码。 bootstrap:数据库初始化相关的代码。 catalog:系统目录(如表和索引的元数据…...
jq命令简易教程——Linux中处理JSON数据的利器
在shell脚本中,当我们需要对JSON数据(例如ceph、kubernetes等一些命令的输出,或是调用API获得的响应)进行处理和提取时,如果使用传统的文本三剑客sed、awk和grep,命令将会非常臃肿不可读。虽然这三个命令在…...
前端开发攻略---Vue实现防篡改水印的效果。删除元素无效!更改元素属性无效!支持图片、元素、视频等等。
1、演示 2、水印的目的 版权保护:水印可以在图片、文档或视频中嵌入作者、品牌或版权所有者的信息,以防止未经授权的复制、传播或使用。当其他人使用带有水印的内容时,可以追溯到原始作者或版权所有者,从而加强版权保护。 身份识…...
在Go语言中复制sync类型
sync包提供了基本的同步原语,例如互斥锁、条件变量和等待组。对于所有这些类型,有一个硬性规则要遵循:它们永远不应该被复制。让我们来理解下这个原理和可能发生的问题。 我们将创建一个线程安全的数据结构来存储计数器。它将包含一个map[string]int,表示每个计数器的当前值…...
Golang | Leetcode Golang题解之第25题K个一组翻转链表
题目: 题解: func reverseKGroup(head *ListNode, k int) *ListNode {hair : &ListNode{Next: head}pre : hairfor head ! nil {tail : prefor i : 0; i < k; i {tail tail.Nextif tail nil {return hair.Next}}nex : tail.Nexthead, tail my…...
【初学】前后端flask+vue组合GET案例
【CSDN 目录配置很不好用】 一、python配置 pip install flaskpip install flask-cors 二、vue配置 1.下载node.js 2.安装node.js 3.测试 node -v4.在vue项目文件夹中创建vue项目 npm create vue@latest第一次会安装一个东西,然后输入名称,一路回车 ✔ Project name…...
计算机科学与技术CS考研408资料
在github上整理了考研的一些资料: 内容包括: 参考书数据结构、组成原理、操作系统、计算机网络.408笔记PDF408思维导图408真题2009-2021真题无logo版408真题2029-2023王道真题(持续更新)历年真题考频统计灰灰考研择校࿰…...
ACID模型是什么
ACID模型是什么 ACID模型是数据库管理系统中保证事务处理安全性的一组特性。ACID是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)四个英文单词的…...
【Linux】基础IO----理解缓冲区
> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:理解缓冲区 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! > 专栏选自:Linux初阶 > 望…...
福州公司建设网站/现在百度怎么优化排名
头文件<functional> 预定义的function object 对对象排序或比较时,默认以less<>为比较准则,因此默认的排序操作总是产生升序. … … Function Adapter和Binder 所谓的Function adapter(函数适配器,函数改造器),指能够将不通的…...
2024免费推广网站/中小企业网站制作
一. 基础环境准备操作系统:Ubuntu16.04Server先sudo apt-get install vim openssh-server,便于后续上传源码以及调试。看一下现在openssh的版本:zjdubuntu:~$ ssh -VOpenSSH_7.2p2 Ubuntu-4ubuntu2.6, OpenSSL 1.0.2g 1 Mar …...
备案变更网站/安卓手机优化软件排名
记录一下自己安装VS2010与Opencv的配置过程,方便以后查看使用,开发环境的搭建: 1. 下载安装Opencv,去官网http://opencv.org/即可下载最新版本的Opencv,此处用的是Opencv 2.4.10 安装时傻瓜式的,最新版本的…...
专业建设网站的/东莞头条最新新闻
先来看看Netty 3.x版本现状 根据对Netty社区部分用户的调查,结合Netty在其它开源项目中的使用情况,我们可以看出目前Netty商用的主流版本集中在3.X和4.X上,其中以Netty 3.X系列版本使用最为广泛。 Netty社区非常活跃,3.X系列版本…...
js做网站登录界面/广告投放怎么做
Pytorch Note55 迁移学习实战猫狗分类 文章目录 Pytorch Note55 迁移学习实战猫狗分类加载数据集迁移学习网络定义训练模型的函数定义一个测试的函数1.AlexNet2.VGG163.ResNet184.DenseNet5.MobileNet V26.ShuffleNetV2总结全部笔记的汇总贴: Pytorch Note 快乐星球 在这一部…...
网站设计 上海/长沙网络推广网站制作
python的类方法和类的静态方法 (2010-03-11 21:27)分类: Pythonpython的类方法和类的静态方法,其实就是一个用classmethod和staticmethod修饰的类中的函数。其中类方法要在定义的时候指出在调用它时隐式赋给他的第一个参数,这个参数一般情况下…...