Java过滤器拦截器的区别和实现
一、什么是过滤器与拦截器?
1.2 拦截器(Interceptor)
java过滤器指的是在java中起到过滤的作用的一个方法。可以在一个请求到达servlet之前,将其截取进行逻辑判断,然后决定是否放行到请求的servlet;也可以在一个response到达客户端之前,截取结果进行逻辑判断,然后决定是否允许返回给客户端。
filter(过滤器) 有如下几个种类(功能):
- 用户授权的filter:filter负责判断用户是否有权限请求该页面。
- 给予过滤判断日志的filter:截取某个用户在本网站上的所有请求。
- 记录轨迹负责解码的filter:规定处理本次请求的解码方式。
需要注意的是,一个filter过滤器可以加在多个servlet控制器上,当然多个filter过滤器也是可以加在一个servlet控制器上的。
由此也是可以看出来,我们使用filter往往是对一些公共的操作进行处理。例如:判断用户权限,解码本次请求等。还比如,我们的web应用中某些页面是需要用户登录后才能访问的,以往我们都是在每个servlet页面加上判断控制,导致代码冗余。有了filter,我们可以定义一个实现了filter的过滤器,让需要判断是否登录的页面都加上这么一个过滤器,可以大大降低代码的冗余程度
1.2 拦截器(Interceptor)
java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。
作用域:动态拦截Action调用的对象(也就是我们的controller层)
在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。 由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
二、过滤器与拦截器的区别
2.1 实现原理不同
- 过滤器的实现基于回调函数
- 拦截器基于Java的反射机制【动态代理】实现。
2.2 使用范围不同
- 过滤器是Servlet的规范,需要实现javax.servlet.Filter接口,Filter使用需要依赖于Tomcat等容器。
- 拦截器是Spring组件,定义在org.springframework.web.servlet包下,由Spring容器管理【又有更加丰富的生缪那个周期处理方法,细粒度,且能够使用Spring中的资源】,不依赖Tomcat等容器。
2.3 触发时机不同
- 过滤器:对请求在进入后Servlet之前或之后进行处理。
- 拦截器:对请求在handler【Controller】前后进行处理。
2.4 执行顺序不同
执行顺序 :Filter 处理中 -> Interceptor 前置 -> 我是controller -> Interceptor 处理中 -> Interceptor 处理后
当有两个过滤器或拦截器时:
过滤器:
每一次都将chain对象传入,达到最后接口回调的效果,类似函数的堆栈调用。
拦截器:
preHandle1 -> preHande2 -> 【Controller】 -> postHandle2 -> postHandle1 -> afterCompletion2 -> afterComplention1
preHandle按照注册顺序,后两个与注册顺序相反。
- 一个拦截器的preHandle为false,则之后的所有拦截器都不会执行。
- 一个拦截器的preHandle为true,则这个拦截器的triggerAfterCompletion一定会执行。
- 只有所有的拦截器preHandler都为true,也就是正常执行,postHandle才会执行。
2.5 控制执行顺序方式不同
实际开发过程中,会出现多个过滤器或拦截器同时存在的情况,不过,有时我们希望某个过滤器或拦截器能优先执行,就涉及到它们的执行顺序。
过滤器用@Order注解控制执行顺序,通过@Order控制过滤器的级别,值越小级别越高越先执行。
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class MyFilter2 implements Filter {}
拦截器默认的执行顺序,就是它的注册顺序,也可以通过Order手动设置控制,值越小越先执行。
@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**").order(2);registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**").order(1);registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").order(3);}
三、过滤器与拦截器的实现
3.1 过滤器实现
过滤器的配置比较简单,直接实现Filter 接口即可,也可以通过@WebFilter注解实现对特定URL拦截,看到Filter 接口中定义了三个方法。
- init() :该方法在容器启动初始化过滤器时被调用,它在 Filter 的整个生命周期只会被调用一次。注意:这个方法必须执行成功,否则过滤器会不起作用。
- doFilter() :容器中的每一次请求都会调用该方法, FilterChain 用来调用下一个过滤器 Filter。
- destroy(): 当容器销毁 过滤器实例时调用该方法,一般在方法中销毁或关闭资源,在过滤器 Filter 的整个生命周期也只会被调用一次
@Component
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("Filter 前置");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("Filter 处理中");filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {System.out.println("Filter 后置");}
}
3.2 拦截器实现
拦截器它是链式调用,一个应用中可以同时存在多个拦截器Interceptor, 一个请求也可以触发多个拦截器 ,而每个拦截器的调用会依据它的声明顺序依次执行。首先编写一个简单的拦截器处理类,请求的拦截是通过HandlerInterceptor 来实现,看到HandlerInterceptor 接口中也定义了三个方法。
- preHandle() :这个方法将在请求处理之前进行调用。注意:如果该方法的返回值为false ,将视为当前请求结束,不仅自身的拦截器会失效,还会导致其他的拦截器也不再执行。
- postHandle():只有在 preHandle() 方法返回值为true 时才会执行。会在Controller 中的方法调用之后,DispatcherServlet 返回渲染视图之前被调用。 有意思的是:postHandle() 方法被调用的顺序跟 preHandle() 是相反的,先声明的拦截器 preHandle() 方法先执行,而postHandle()方法反而会后执行。
- afterCompletion():只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。
@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("Interceptor 前置");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("Interceptor 处理中");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("Interceptor 后置");}
}
将自定义好的拦截器处理类进行注册,并通过addPathPatterns、excludePathPatterns等属性设置需要拦截或需要排除的 URL。
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");}
}相关文章:
Java过滤器拦截器的区别和实现
一、什么是过滤器与拦截器? 1.2 拦截器(Interceptor) java过滤器指的是在java中起到过滤的作用的一个方法。可以在一个请求到达servlet之前,将其截取进行逻辑判断,然后决定是否放行到请求的servlet;也可以在…...
Android 12 系统开机动画
修改Android开机动画有两种方式 方式一、通过adb 命令来修改: 进入/system/media目录,将里面的 bootanimation.zip 文件pull出来,然后解压,替换part0和part1中的图片,并且根据图片大小修改文件 desc.txt 中的内容&…...
C++:异常体系
异常体系 异常1.C语言传统的处理错误的方式2.C异常概念3.异常的使用3.1异常的抛出和捕获3.2 异常的重新抛出3.3异常安全3.4 异常规范 4.C标准库的异常体系5.异常的优缺点 异常 1.C语言传统的处理错误的方式 终止程序,如assert,缺陷:用户难以…...
民事二审案件庭审应如何准备?
一、你要明确审理范围,固定上诉请求 首先,第二审人民法院围绕当事人的上诉请求进行审理。 其次,在第二审程序中,原审原告增加独立的诉讼请求或者原审被告提出反诉的,第二审人民法院可以根据当事人自愿的原则就新增加的…...
WebRTC系列-H264视频帧组包(视频花屏问题)
文章目录 工具函数是否满足组帧条件函数PotentialNewFrame更新丢失包记录 UpdateMissingPackets重要属性1. InsertPacket2. FindFramesWebRTC在弱网环境下传输较大的视频数据,比如:屏幕共享数据;会偶发的出现黑屏的问题;也就是说当视频的码率比较大且视频的分辨率比较高的时…...
Common Mistakes in German
Comman Mistakes in German 1, Haus oder Hause2, ja nein oder doch(1) Positive Fragen(2) Negative Fragen 1, Haus oder Hause 2, ja nein oder doch (1) Positive Fragen (2) Negative Fragen kein / nicht P3...
Java基础数据结构之反射
一.定义 Java的反射机制是在运行状态中的,对于任意一个类都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法及属性。既然能拿到,我们就可以修改部分类型信息。这种动态获取信息以及动态调用对象方法的功能…...
【实战系列----消息队列 数据缓存】rabbitmq 消息队列 搭建和应用
线上运行图,更新不算最新版,但可以使用修改线程等补丁功能,建议使用新版本。 远程服务器配置图: 这个可以更具体情况,因为是缓存队列理所当然 内存越大越好,至于核心4核以上足够使用。4核心一样跑 这里主要是需要配置服…...
【云原生kubernetes系列】---亲和与反亲和
1、亲和和反亲和 node的亲和性和反亲和性pod的亲和性和反亲和性 1.1node的亲和和反亲和 1.1.1ndoeSelector(node标签亲和) #查看node的标签 rootk8s-master1:~# kubectl get nodes --show-labels #给node节点添加标签 rootk8s-master1:~# kubectl la…...
【极简】Pytorch中的register_buffer()
register buffer 定义模型能用torch.save保存的、但是不更新参数。 使用:只要是nn.Module的子类就能直接self.调用使用: class A(nn.Module): #... self.register_buffer(betas, torch.linspace(beta_1, beta_T, T).double()) #...手动定义参数 上述…...
J-Link:STM32使用J-LINK烧录程序,其他MCU也通用
说明:本文记录使用J-LINK烧录STM32程序的过程。 1. J-LINK驱动、软件下载 1、首先拥有硬件J-Link烧录器。 2、安装J-Link驱动程序SEGGER 下载地址如下 https://www.segger.com 直接下载就可以了。 2.如何使用J-LINK向STM32烧写程序 1、安装好以后打开J-LINK Fl…...
从0到1入门C++编程——06 类和对象之多态、文件操作
文章目录 多态1.多态基本概念2.多态案例——计算器3.纯虚函数和抽象类4.多态案例——制作饮品5.虚析构和纯虚析构6.多态案例——电脑组装 文件操作1.文本文件--写文件2.文本文件--读文件3.二进制文件--写文件4.二进制文件--读文件 多态 1.多态基本概念 多态是C面向对象的三大…...
elementUI实现selecttree自定义下拉框树形组件支持多选和搜索
elementUI实现selecttree自定义下拉框树形组件支持多选和搜索 效果图定义子组件父组件应用 效果图 定义子组件 主要结合el-select和el-tree两个组件改造的。 <template><div class"selectTree"><el-select filterable :filter-method"filterMe…...
使用 Spring Boot 构建 Docker 镜像的简易指南
Spring Boot 是一个用于创建独立的、生产级别的 Spring 应用程序的框架。结合 Docker,你可以方便地将你的 Spring Boot 应用程序打包成一个容器镜像,实现更加灵活和可移植的部署。本文将指导你如何使用 Docker 构建一个包含 Spring Boot 应用程序的镜像。…...
「数据结构」3.ArrayList
🎇个人主页:Ice_Sugar_7 🎇所属专栏:Java数据结构 🎇**欢迎点赞收藏加关注哦!* ArrayList 🍉ArrayList的构造🍉add方法🍌扩容机制🍌重要结论 🍉其…...
H.264与H.265的主要差异
H.265仍然采用混合编解码,编解码结构域H.264基本一致, H.265与H.264的主要不同 编码块划分结构:采用CU (CodingUnit)、PU(PredictionUnit)和TU(TransformUnit)的递归结构。 并行工具:增加了Tile以及WPP等并行工具集以提高编码速…...
【数据结构】 归并排序超详解
1.基本思想 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列,即先使每个子序列有序…...
Debezium系列之:深入理解GTID全局事务标识,并记录一次数据库重启造成数据丢失的原因和解决方案
Debezium系列之:深入理解GTID,并记录一次数据库重启造成数据丢失的原因和解决方案 一、背景二、深入理解什么是GTID三、深入理解gtid的uuid部分四、判断GTID之间的顺序大小五、解决方案一、背景 hive数据库的表与源头业务数据库的数据不一致,经过检查发现源头数据库发生了重…...
格式化内存卡后,如何找回丢失的监控视频?
随着摄像头的应用越来越广泛,很多监控摄像头采用了内存卡作为存储介质,方便用户存储和查看摄像头拍摄的视频文件。然而,由于各种原因,监控摄像头的内存卡有时会被意外格式化导致重要数据的丢失,给用户带来诸多困扰。 那…...
《动手学深度学习(PyTorch版)》笔记4.8
注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过。…...
告别手动调参!用Simulink扫频法+PID Tuner,10分钟搞定升降压电路的PI控制器设计
10分钟自动化PI设计:Simulink扫频与PID Tuner在升降压电路中的实战技巧 电力电子工程师们对这样的场景一定不陌生:面对一个全新的升降压电路拓扑,为了获得稳定的输出电压,不得不花费数小时甚至数天时间反复调整PI控制器的参数。传…...
灵毓秀-牧神-造相Z-Turbo使用全攻略:从环境检查到作品输出
灵毓秀-牧神-造相Z-Turbo使用全攻略:从环境检查到作品输出 1. 镜像简介与核心功能 灵毓秀-牧神-造相Z-Turbo是一款基于Xinference部署的AI文生图模型服务,专门用于生成《牧神记》中灵毓秀角色的高质量图像。该镜像集成了Gradio交互界面,让用…...
YOLOFuse实战案例:如何利用红外+RGB融合提升森林火情监测精度
YOLOFuse实战案例:如何利用红外RGB融合提升森林火情监测精度 1. 森林火情监测的痛点与挑战 森林火灾是全球性的生态灾难,每年造成巨大经济损失和生态破坏。传统监测手段主要依赖可见光摄像头和人工巡查,存在明显局限性: 夜间失…...
通义千问1.8B-Chat部署教程:Supervisor管理服务,稳定运行不中断
通义千问1.8B-Chat部署教程:Supervisor管理服务,稳定运行不中断 1. 项目概述 通义千问1.5-1.8B-Chat-GPTQ-Int4是阿里云推出的轻量级对话模型,经过GPTQ-Int4量化后,显存需求仅约4GB,非常适合在消费级GPU或边缘设备上…...
Lingbot-Depth-Pretrain-ViTL-14在互联网内容审核中的深度场景理解应用
Lingbot-Depth-Pretrain-ViTL-14在互联网内容审核中的深度场景理解应用 每天,互联网上都会产生数以亿计的图片和视频。对于平台的内容审核团队来说,这既是流量的盛宴,也是巨大的挑战。传统的审核方式,无论是依赖人工还是基于二维…...
CLIP-GmP-ViT-L-14图文匹配工具实测:电商搜图、智能相册应用场景解析
CLIP-GmP-ViT-L-14图文匹配工具实测:电商搜图、智能相册应用场景解析 你有没有想过,当你在电商平台用一张随手拍的照片搜索商品时,背后的技术是怎么工作的?或者,当你对着手机相册输入“去年夏天在海边拍的日落”&…...
UEFI SCT编译调试踩坑记:我的AARCH64环境搭建与问题解决实录
UEFI SCT编译调试实战:AARCH64环境搭建与疑难问题全解析 当你在深夜的办公室里盯着屏幕上闪烁的光标,第N次尝试编译UEFI SCT测试套件时,那种既熟悉又陌生的挫败感再次袭来。作为UEFI开发者,我们都经历过这样的时刻——官方文档看似…...
益象创新与数谷智能,轻量化 AI 定制方案设计谁更优?
在企业数字化转型的下半场,人工智能(AI)的应用正从“大算力、大模型”的盲目崇拜,转向“轻量化、高适配”的务实落地上。对于中小型企业或大型企业的特定业务部门而言,动辄百万级的算力投入并不现实,一套能…...
苹果设备激活锁终极解锁指南:5步免费绕开iOS 15-16的iCloud限制
苹果设备激活锁终极解锁指南:5步免费绕开iOS 15-16的iCloud限制 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 还在为忘记Apple ID密码而无法使用自己的iPhone或iPad而烦恼吗?…...
郭老师-悟性高的人,为何不合群?
悟性高的人,为何不合群? ——他们在独处中,与道同行“你以为他孤独, 其实—— 他正与万物对话。”🌿 不合群,不是缺陷, 而是—— 为悟性留出呼吸的空间。🧘 一、独处 ≠ 孤独&#x…...
