Springboot项目快速实现过滤器功能
前言
很多时候,当你以为掌握了事实真相的时间,如果你能再深入一点,你可能会发现另外一些真相。比如面向切面编程的最佳编程实践是AOP,AOP的主要作用就是可以定义切入点,并在切入点纵向织入一些额外的统一操作,避免与业务代码过度耦合。熟悉java web项目的都知道,另外还有过滤器(filter)、拦截器(interceptor)也有类似AOP的功能特性,那么问题来了:为什么一般说面向切面编程就是指AOP,而不是过滤器和拦截器?过滤器和拦截器在Spring boot中怎么实现?这三者之间有什么区别?Springboot项目快速实现Aop功能中分享了AOP的相关实现,下面将再用两到三篇文章,分别和大家分享一下过滤器、拦截器的实现,以及AOP、过滤器、拦截器之间的横向对比,以便在业务开发中,能够快速、正确选对具体实现方法。
环境配置
jdk版本:1.8
开发工具:Intellij iDEA 2020.1
springboot:2.3.9.RELEASE
Filter简介
Filter, 中文意思是过滤器,Filter的全限定类名是javax.servlet.Filter,可以看出这是与servelt相关的一个接口;SpringMVC核心是DispatcherServlet,而DispatcherServlet又继承了Servlet,进而可以推测出Filter与SpringMVC也是关联关系。

事实上这样的推测也是正确的,在SpringMVC项目中,filter在浏览器与服务器之间起过滤的作用,可以截取客户端和服务端之间的请求和响应信息,并根据这些请求-响应信息作一些其他的操作,但是要注意,filter并不能改变请求-响应信息;
核心类
Filter
Filter接口的全限定类名是javax.servlet.Filter,该接口有三个方法,分别是
1、init(...):用于初始化Filter;
2、doFilter(...):过滤请求和拦截响应信息的具体实现在这个方法里;
3、destroy(...):Filter对象被销毁时触发,主要用于做一些收尾工作,如资源的释放等;
FilterConfig
FilterConfig接口的全限定类名是javax.servlet.FilterConfig,该接口主要有四个方法,分别是:
1、getFilterName() 获取Filter的名字;
2、getServletContext() 获取ServletContext对象(即application);
3、getInitParameter() 获取Filter的初始化参数;
4、getInitParameterNames() 获取所有初始化参数的名字;
FilterChain
FilterChainr接口的全限定类名是javax.servlet.FilterChain,该接口只有一个方法,是doFilter()方法,用于调用Filter链上的下一个过滤器,如果当前过滤器为最后一个或只有一个过滤器,则该过滤器则将请求发送到目标资源。
MyFilter2是自己实现的过滤器,实现了Filter接口;Filter接口依赖FilterChain接口和FilterConfig接口,其中FilterChain接口的实现类是org.apache.catalina.core.ApplicationFilterChain,FilterConfig接口的实现类是org.apache.catalina.core.ApplicationFilterConfig;

工作原理
1、项目启动的时候,先执行Filter的构造方法,完成相关Filter对象的注册;
2、紧接着,Filter对象的init()方法被调用,开始对Filter做一些初始化操作;
3、项目启动完成后,客户端每次向服务端发起请求时,如果请求地址与过滤器定义的地址匹配,则会执行Filter的doFilter();如果匹配上多个过滤器,则会形成一个链路,依次调用各个过滤器对象的doFilter();服务端作出响应后,也会再次执行到各个过滤器对象的doFilter();请求和响应时,过滤器链的执行顺序是先进后出;
4、服务器停止时调用Filter的destroy()方法,用来释放资源。

实现方式
Springboot项目中一般有两种方式:
1、@WebFilter注解,即javax.servlet.annotation.WebFilter;
2、FilterRegistrationBean,即org.springframework.boot.web.servlet.FilterRegistrationBean;
两种方式,都需要在启动类上增加注解@ServletComponentScan,用于开启servlet相关bean的扫描,其中包含有过滤器(Filter);
@SpringBootApplication
@ServletComponentScan
public class FanfuApplication {public static void main(String[] args) {SpringApplication.run(FanfuApplication.class, args);}
}代码实现
1、WebFilter注解里,定义一下过滤器的名字,以及要对哪些请求进行过滤,“/*”表示对所有的请求都过滤,在实际业务中,可具体对待;如果在初始化的时候,需要携带一些初始化的参数,可以在initParams属性上,使用@WebInitParam注解来定义初始化参数名称和具体的值,这些参数可以在filter对象初始化的时候获取到;MyFIlter1和MyFIlter2使用的注解方式定义的过滤器;
@Slf4j
@WebFilter(filterName = "myFilter1", urlPatterns = "/*", initParams = {@WebInitParam(name = "creator", value = "fanfu")})
public class MyFilter1 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("//myFilter1初始化开始");String creator = filterConfig.getInitParameter("creator");log.info("//初始化参数creator:{}",creator);}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {log.info("//myFilter1开始执行");chain.doFilter(request, response);log.info("//myFilter1结束执行");}@Overridepublic void destroy() {log.info("//myfilter1被销毁");}
}@Slf4j
@WebFilter(filterName = "myFilter2", urlPatterns = "/*")
public class MyFilter2 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("//myFilter2初始化开始");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {log.info("//myFilter2开始执行");chain.doFilter(request, response);log.info("//myFilter2结束执行");}@Overridepublic void destroy() {log.info("//myFilter2被销毁");}
}2、FilterRegistrationBean方式
在Springboot项目的配置类中,使用FilterRegistrationBean来包装自定义的过滤器,这种方式的最大好处就是可以自定义过滤器的执行顺序,数字越小,执行时的优先级就越高;MyFIlter3和MyFIlter4是使用FilterRegistrationBean方式定义的过滤器;
@Configuration
public class WebConfig {@Beanpublic FilterRegistrationBean filterRegistration1() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(new MyFilter3());filterRegistrationBean.addUrlPatterns("/*");//定义过滤器对哪些请求路径进行过滤,/*表示对所有请求都过滤filterRegistrationBean.setOrder(2);//定义过滤器的执行优先级,数据越小优先级越高return filterRegistrationBean;}@Beanpublic FilterRegistrationBean filterRegistration2() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(new MyFilter4());filterRegistrationBean.addUrlPatterns("/*");filterRegistrationBean.setOrder(1);return filterRegistrationBean;}
}@Slf4j
public class MyFilter3 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("//MyFilter3初始化开始");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {log.info("//MyFilter3开始执行");chain.doFilter(request,response);log.info("//MyFilter3结束执行");}@Overridepublic void destroy() {log.info("//MyFilter3被销毁");}
}@Slf4j
public class MyFilter4 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("//MyFilter4初始化开始");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {log.info("//MyFilter4开始执行");chain.doFilter(request,response);log.info("//MyFilter4结束执行");}@Overridepublic void destroy() {log.info("//MyFilter4被销毁");}
}未定义myFilter3、myFilter4的执行优先级,即采取自然排序时的执行结果:在请求前myFilter3的执行时机早于myFilter4,响应后myFilter3的执行时机要晚于myFilter4;

定义myFilter4的优先级高于myFilter3时,执行结果:在请求前myFilter4的执行时机早于myFilter3,响应后的myFilter4的执行时机要晚于myFilter3;

总结
过滤器的实现是比较简单,通过梳理这个过程,我get到以下几个点:
1、过滤器是用于SpringMVC项目中,即与servlet相关的项目;
2、过滤器的执行时机是在请求前和响应后,有两种实现方式,即@WebFilter注解和FilterRegistrationBean;如果对过滤器的执行顺序没有限制要求,则可以使用第一种;如果对过滤器的执行顺序有明确限制,则可以使用第二种;
3、如果有多个过滤器对象时,会形成一个过滤器链,过滤器的执行顺序是先进后出;
4、过滤器可以过滤请求和拦截响应,但是不能改变请求值和响应值;
相关文章:
Springboot项目快速实现过滤器功能
前言很多时候,当你以为掌握了事实真相的时间,如果你能再深入一点,你可能会发现另外一些真相。比如面向切面编程的最佳编程实践是AOP,AOP的主要作用就是可以定义切入点,并在切入点纵向织入一些额外的统一操作࿰…...
基于springboot的简历系统的实现
摘 要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,简历系统当然也不能排除在外。简历系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用…...
Vue3中watch的用法
watch函数用于侦听某个值的变化,当该值发生改变后,触发对应的处理逻辑。 一、watch的基本实例 <template><div><div>{{ count }}</div><button click"changCount">更改count的值</button></div> …...
MS python学习(18)
学习Pandas.DataFrame(2) load csv(comma seperated variable) files to DataFrame and vice versa upload csv files read/write csv files load data into jupyter notebook, create a new folder and then upload the csv files into it. (CSV comma seperated variable)…...
java笔记
前言 以下是一名java初学者在自学过程中所整理的笔记,欢迎大家浏览并留言,若有错误的地方请大家指正。 java语言特性 简单性:相对于其他编程语言而言,java较为简单,例如:java不再支持多继承,C…...
对象的构造及初始化
目录 一、如何初始化对象 二、构造方法 1.概念 2.特性 三、默认初始化 四、就地初始化 总结 一、如何初始化对象 在Java方法内部定义一个局部变量的时候,我们知道必须要进行初始化。 public class Test4 {public static void main(String[] args) {//未初始化…...
Socket 读取数据
1. Socket 配置参数中添加 1.1 读取 Socket 字节时的字节序 1.2 读取数据时,单次读取最大缓存值 1.3 从 Socket 读取数据时,遵从的数据包结构协议 1.4 服务器返回数据的最大值,防止客户端内存溢出 /*** Description: Socket 配置参数*/public…...
小白的Git入门教程(一)
这是本人的git的入门过程仅供参考 先是在官网下载git版本下载链接,安装步骤可以搜索其他大神的文章然后就是创建一个属于你的git本地库首先是创建一个文件夹作为根目录,这里我创建了一个叫test_git文件夹紧接着便进去新建文件夹,点击这里的g…...
第一个Vue程序
第一个Vue程序 <body> <!--view层 变成了一个模板--> <div id"app">{{message}} </div><!--导入vue.js--> <script src"https://cdn.jsdelivr.net/npm/vue2.5.16/dist/vue.min.js"></script> <script>va…...
2023上学期学习计划
目前:根据答辩的情况来看,目前去项目组,着重写好算法是相对较优的打算,先将项目写好,之后着重提升算法水平,这学期主要啃《算法导论》与《大话数据结构》这俩本书,同时刷题量要达到160题 四月份…...
深入了解MySQL锁机制及应用场景
深入了解MySQL锁机制及应用场景锁的概述锁的分类锁的应用场景数据库事务管理多线程程序开发数据库的备份和恢复对于在线游戏等高并发应用场景锁的具体使用方法锁的应用实例总结锁的概述 MySQL锁是操作MySQL数据库时常用的一种机制。MySQL锁可以保证多个用户在同时执行读写操作…...
Java类和对象
目录 一、什么是面向对象? 二、类与对象的基本概念 1.类 2.对象 三、类的定义格式 四、类与对象的定义与使用 1.什么是实例化 2.实例化对象 3.类的使用 4.类与对象的说明 总结 一、什么是面向对象? 面向对象是一种现在最为流行的程序设计方法&a…...
aspnet053+sqlserver在线考试系统xns
目 录 基于.NET的考试系统 1 摘 要 3 前 言 4 第一章 系统概述 5 1.1 本课题的研究意义 5 1.2 本论文的目的及内容 5 第二章 在线考试系统概述 7 2.1 现行在线考试系统现状 7 2.2 电子管理平台的开发方法介绍 8 2.2.1 B/S体系结构 8 2…...
新一代大学英语(提高篇)
词汇题(55道) 1. You should carefully think over_____ the manager said at the meeting. A. that B. which C. what D. whose 1.选C,考察宾语从句连接词,主句谓语动词think over后面缺宾语,后面的宾语从句谓语动…...
阿里云OSS 203 Non-Authoritative Information问题解决
问题描述: 203 Non-Authoritative Information 问题分析: 1、跨域问题,阿里云OSS没有配置跨域规则。 解决办法请参考以下博客。 阿里云OSS No ‘Access-Control-Allow-Origin‘ header is present on the requested resource问题解决_旭东…...
【数据结构】你真的认识“”吗?它真的就只是“取地址”吗?或许你一直都在误解它。
我们有时候在看数据结构相关书籍时,经常会看到这样的写法: void StackInit(ST& ps) {assert(ps);ps.a NULL;ps.top 0;ps.capacity 0; } 注意,这里的&可不是表示取地址。如果你把它理解为取地址,那就在错误的路上狂奔&…...
[深入理解SSD 21] 固态硬盘GC机制 | GC 分类 | GC 过程 | GC 和 Trim 的关系
Hello 大家好, 我是元存储~主页:元存储的博客_CSDN博客-深入理解SSD:固态存储特性与实践,深入浅出SSD:固态存储原理与特性,深入理解Flash:闪存特性与实践领域博主前言SSD上已经被写入过的Page页在重新被写入之前,必须要将page页所在的block块…...
大数据未来发展怎么样?
就目前情况来看,大数据行业前景不错薪资待遇好,也有越来越多的人选择大数据行业,各大名企对于大数据人才需求不断上涨。 大数据从业领域很宽广,不管是科技领域还是食品产业,零售业等都是需要大数据人才进行大数据的处…...
【Linux】进程和线程间的区别与联系
带你轻松理解进程与线程的区别与联系: 进程线程定义资源分配和拥有的基本单位CPU调度的基本单位切换情况对应进程的CPU环境的保存以及新进程环境的设置保存和设置程序计数器,少量的寄存器,以及对应的线程栈切换者操作系统操作系统切换过程用…...
【C语言】变量和常量
目录 1. 变量 1.1 变量的分类 1.1.1 局部变量 1.1.2 全局变量 1.2 变量的使用——声明、赋值、初始化 1.3 变量的作用域和生命周期 1.3.1 作用域 1.3.2 生命周期 2. 常量 2.1 字面常量 2.2 常变量(const常量) 2.3 简单的宏(对象式…...
手把手教你用Transceiver Wizard搞定UltraScale FPGA的GTY时钟网络规划
手把手教你用Transceiver Wizard搞定UltraScale FPGA的GTY时钟网络规划 在FPGA高速收发器设计中,时钟网络的合理规划往往是决定系统稳定性的关键因素。对于刚接触Xilinx UltraScale架构的开发者来说,GTY收发器的时钟分配规则就像一座迷宫——相邻Bank共享…...
Open Event Server数据导入导出完全指南:支持JSON、XML、iCal格式的终极教程
Open Event Server数据导入导出完全指南:支持JSON、XML、iCal格式的终极教程 【免费下载链接】open-event-server The Open Event Organizer Server to Manage Events https://test-api.eventyay.com 项目地址: https://gitcode.com/gh_mirrors/op/open-event-ser…...
MiniCPM-o-4.5-nvidia-FlagOS开源镜像:FlagOS软件栈赋能的NVIDIA GPU原生推理方案
MiniCPM-o-4.5-nvidia-FlagOS开源镜像:FlagOS软件栈赋能的NVIDIA GPU原生推理方案 想快速体验一个能看懂图片、还能跟你聊天的AI助手吗?今天要介绍的MiniCPM-o-4.5-nvidia-FlagOS开源镜像,就是一个开箱即用的多模态AI解决方案。它基于FlagOS…...
Chrome 安全机制深度解析(二)告别 unsafe-inline:CSP 进阶实战与攻防博弈,构建真正无法绕过的内容防线
配置了 CSP 依然被 XSS 打穿,问题往往不在攻击有多高明,而在于你始终舍不得删掉那两个词:unsafe-inline、unsafe-eval。真正的强安全 CSP,从来不是妥协的产物,而是一套从策略设计到工程落地的完整体系。上一篇我们讲到…...
AI在测试中的应用:从测试用例生成到缺陷预测
随着软件开发流程向敏捷与DevOps的持续演进,软件测试面临着迭代周期缩短、系统复杂度飙升的双重压力。传统的测试方法,高度依赖人工经验与重复劳动,在效率、覆盖率和预测性上逐渐显现瓶颈。人工智能技术的引入,正从辅助工具演变为…...
济南精神心理专科:如何识别躯体化障碍的早期信号
济南躯体化障碍疾病就医选择难题在济南,面对躯体化障碍疾病的朋友最关心的是隐私和靠谱。选择一家好的医院至关重要,尤其是看躯体化障碍一定要选专科专业医院。这类医院不仅在专业诊疗上更有优势,还能提供更好的隐私保护和服务体验。本文将基…...
硅橡胶资源平台对接的靠谱对接企业哪家强
在深圳这座创新与制造之都,硅橡胶产业上下游企业林立,从原材料、模具设计到制品生产,形成了一个庞大而复杂的产业链。对于许多企业而言,“深圳硅橡胶资源平台对接” 的需求日益迫切——无论是寻找稳定供应商、开拓新客户ÿ…...
Kotlin 2.4.0 正式发布,快来看看有哪些更新
昨日,JetBrains 发布了 Kotlin 2.4.0-Beta1。 如果你管的是 Android 工具链、Kotlin 多平台,或者团队里已经开始碰 context receivers、注解处理、.klib 兼容问题,这个版本已经值得单独开分支验证。 先说结论 这次最有分量的变化࿰…...
MusePublic助力Java开发者:SpringBoot集成指南
MusePublic助力Java开发者:SpringBoot集成指南 1. 为什么Java团队需要MusePublic能力 最近帮一家电商公司做推荐系统升级时,技术负责人跟我聊起一个现实问题:他们用传统协同过滤算法生成的商品推荐列表,点击率已经连续三个季度停…...
IT行业的项目经理考不考PMP证书?我劝你看完这篇在决定!
作为在 IT 圈摸爬滚打 8 年,从后端开发一路转型项目经理、带过 10 大小项目的老学长,最近总被身边技术小伙伴追问:想转 PM,必须考 PMP 吗?没证书就做不好项目管理吗?今天就用过来人的经验,跟大…...
