04-过滤器和拦截器有什么区别?【Java面试题总结】
过滤器和拦截器有什么区别?
- 运行顺序不同:过滤器是在 Servlet 容器接收到请求之后,但在 Servlet被调用之前运行的;而拦截器则是在Servlet 被调用之后,但在响应被发送到客户端之前运行的。

- 过滤器Filter 依赖于 Servlet 容器,属于Servlet规范的一部分,可以在web.xml中进行配置或者使用注解(如
@WebFilter)进行配置;而 拦截器Interceptor 不依赖于 Servlet 容器,一般可以在Spring配置文件中进行配置或使用注解(如@Interceptor)来配置拦截器; - Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行;
- Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。
知识扩展:
过滤器的使用场景:
- 身份验证:对请求进行身份验证,检查用户是否登录或具有访问权限。
- 请求日志记录:记录请求的详细信息,如URL、参数、请求时间等。
- 数据加工:对请求或响应的数据进行处理,例如压缩、解密、加密等。
- 编码转换:对请求和响应的编码进行转换,以适应不同的字符编码要求。
简单的过滤器代码案例,用于记录请求的访问日志、请求时间记录:
新建LoggingFilter实现Filter类,获取request中的方法、URL,在过滤器链执行完成前后分别记录时间来获取请求处理时间
package com.springboot.learn.filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** <p>Class: LoggingFilter</p>* <p>Description: 日志Filter</p>** @author zhouyi* @version 1.0* @date 2023/8/28*/
public class LoggingFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化方法}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {long start = System.nanoTime();HttpServletRequest httpRequest = (HttpServletRequest) request;String requestURI = httpRequest.getRequestURI();String method = httpRequest.getMethod();System.out.println("Request received - Method: " + method + ", URI: " + requestURI + " ,useTime:" + (System.nanoTime() - start));// 继续执行请求链chain.doFilter(request, response);}@Overridepublic void destroy() {// 销毁方法}
}
在Servlet 中,我们需要在web.xml中配置过滤器,在SpringBoot中没有web.xml的概念,我们通过其他方式配置,如下
方式一:通过FilterRegistrationBean来配置
FilterRegistrationBean是Spring Boot提供的一个用于注册和配置过滤器的辅助类。它允许你以编程的方式定义过滤器,并将其注册到Servlet容器中。FilterRegistrationBean提供了一系列方法来配置过滤器的属性,包括过滤器实例、URL匹配模式、过滤器执行顺序、Dispatcher类型等。
通过使用FilterRegistrationBean,你可以更灵活地配置过滤器,并且不依赖于传统的基于web.xml配置的方式。你可以将FilterRegistrationBean作为一个Spring Bean进行管理,可以通过注入方式获取并设置过滤器的属性
@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean registFilter() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new LoggingFilter());registration.addUrlPatterns("/*");registration.setName("LoggingFilter");registration.setOrder(1);return registration;}
}
常见用法
setFilter(Filter filter):设置过滤器实例。addUrlPatterns(String... urlPatterns):设置URL匹配模式,指定过滤器要拦截的URL路径模式。setOrder(int order):设置过滤器的执行顺序,数字越小越先执行。setDispatcherTypes(DispatcherType... dispatcherTypes):设置过滤器的Dispatcher类型,指定过滤器要拦截的请求类型,如REQUEST、FORWARD、INCLUDE、ASYNC等。- 其他方法还包括设置过滤器名称、初始化参数、是否启用异步支持等。
功能验证
@RestController
@RequestMapping("/test")
public class TestController {@GetMapping("/user")public String queryUser(String id) {return id;}
}
访问接口请求,发现控制台已打印出我们想要的信息。


方式二:通过@WebFilter注解实现
在过滤器中添加注解 @WebFilter进行配置,同样可以设置url匹配模式,过滤器名称等。
/*** <p>Class: LoggingFilter2</p>* <p>Description: 日志Filter</p>** @author zhouyi* @version 1.0* @date 2023/8/28*/
@WebFilter(urlPatterns = "/*", filterName = "LoggingFilter2")
public class LoggingFilter2 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化方法}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {long start = System.nanoTime();HttpServletRequest httpRequest = (HttpServletRequest) request;String requestURI = httpRequest.getRequestURI();String method = httpRequest.getMethod();System.out.println("【LoggingFilter2】Request received - Method: " + method + ", URI: " + requestURI + " ,useTime:" + (System.nanoTime() - start));// 继续执行请求链chain.doFilter(request, response);}@Overridepublic void destroy() {// 销毁方法}
}
注意,@WebFilter这个注解是Servlet3.0的规范,并不是Spring boot提供的。除了这个注解以外,我们还需在配置类中加另外一个注解:@ServletComponetScan,指定扫描的包,放在启动类上面。

访问请求,发现过滤器的两种配置方式均已实现

拦截器的使用场景:
- 权限检查:在请求处理方法执行之前,检查用户是否具有执行该操作的权限。
- 日志记录:记录请求的详细信息、处理时间等,用于跟踪和监控。
- 数据转换:在请求处理方法执行前后,对请求或响应的数据进行转换和处理。
- 异常处理:捕获请求处理方法中抛出的异常,并进行相应的处理和响应。
在SpringBoot中实现拦截器有两种方式
(1)实现HandlerInterceptor接口,并实现相应的方法
(2)继承HandlerInterceptorAdapter类,并重写里面的方法
方式一:实现HandlerInterceptor接口
public class LoggingInterceptor implements HandlerInterceptor {long start = System.nanoTime();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理方法执行之前的预处理逻辑start = System.nanoTime();// 返回 true 表示继续执行后续的拦截器和请求处理方法,返回 false 表示终止执行return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在请求处理方法执行之后的后处理逻辑HttpServletRequest httpRequest = (HttpServletRequest) request;String requestURI = httpRequest.getRequestURI();String method = httpRequest.getMethod();System.out.println("【HandlerInterceptor】Request received - Method: " + method + ", URI: " + requestURI + " ,useTime:" + (System.nanoTime() - start));}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在视图渲染完成后的清理逻辑}
}
配置拦截器
@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 可添加多个,/**是对所有的请求都做拦截registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/register");}
}
运行时发现拦截器也生效


方式二:继承HandlerInterceptorAdapter类
public class LoggingInterceptor2 extends HandlerInterceptorAdapter {long start = System.nanoTime();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理方法执行之前的预处理逻辑start = System.nanoTime();// 返回 true 表示继续执行后续的拦截器和请求处理方法,返回 false 表示终止执行return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在请求处理方法执行之后的后处理逻辑HttpServletRequest httpRequest = (HttpServletRequest) request;String requestURI = httpRequest.getRequestURI();String method = httpRequest.getMethod();System.out.println("【LoggingInterceptor2】Request received - Method: " + method + ", URI: " + requestURI + " ,useTime:" + (System.nanoTime() - start));}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在视图渲染完成后的清理逻辑}
}
通过继承HandlerInterceptorAdapter类来实现拦截器的方式,也需要配置拦截器。和方式一的配置是一样的
@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 可添加多个,/**是对所有的请求都做拦截registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/register");registry.addInterceptor(new LoggingInterceptor2()).addPathPatterns("/**").excludePathPatterns("/login", "/register");}
}
运行时发现,两种方式的拦截器均已实现。


相关文章:
04-过滤器和拦截器有什么区别?【Java面试题总结】
过滤器和拦截器有什么区别? 运行顺序不同:过滤器是在 Servlet 容器接收到请求之后,但在 Servlet被调用之前运行的;而拦截器则是在Servlet 被调用之后,但在响应被发送到客户端之前运行的。 过滤器Filter 依赖于 Servle…...
如何用selenium或pyppeteer来启动多个AdsPower窗口
前言 本文是该专栏的第57篇,后面会持续分享python爬虫干货知识,记得关注。 关于selenium或pyppeteer来启动打开adspower浏览器的方法,笔者在本专栏前面有详细介绍过,感兴趣的同学可往前翻阅《如何用selenium或pyppeteer来链接并打开指纹浏览器AdsPower》,文章内容包含完整…...
京东店铺所有商品API接口数据
京东平台店铺所有商品数据接口是开放平台提供的一种API接口,通过调用API接口,开发者可以获取京东整店的商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片、价格信息等详细信息 。 获取店铺所有商品接口API是一种用于获取电商平台上商…...
stm32之27.iic协议oled显示
屏幕如果无法点亮,需要用GPIO_OType_PP推挽输出,加并上拉电阻 1.显示字符串代码 2.显示图片代码(unsigned强制转换(char*)) 汉字显示...
paddle 1-高级
目录 为什么要精通深度学习的高级内容 高级内容包含哪些武器 1. 模型资源 2. 设计思想与二次研发 3. 工业部署 4. 飞桨全流程研发工具 5. 行业应用与项目案例 飞桨开源组件使用场景概览 框架和全流程工具 1. 模型训练组件 2. 模型部署组件 3. 其他全研发流程的辅助…...
ChatGPT帮助高职院校学生实现个性化自适应学习与对话式学习
一、学习层面:ChatGPT帮助高职院校学生实现个性化自适应学习与对话式学习 1.帮助高职院校学生实现个性化自适应学习 数字技术的飞速发展引起了教育界和学术界对高职院校学生个性化自适应学习的更多关注和支持,其运作机制依赖于人工智能等技术࿰…...
如何通过python写接口自动化脚本对一个需要调用第三方支付的报名流程进行测试?
对于需要调用第三方支付的报名流程进行接口自动化测试,可以通过以下步骤来编写Python代码: 1. 确认API需求 首先,需要确认报名流程的API需求和预期功能。这涉及到对业务需求的理解和API设计的分析。 2. 安装依赖库 在Python程序中&#x…...
将OSGB格式数据转换为3d tiles的格式
现有需求需要将已有的一些OSGB数据加载到CesiumJS中展示,但是CesiumJS本身不支持osbg格式的数据渲染所以我们需要将其转换一下,有两种格式可以转换一种是glTF格式,另一种是我们今天要介绍的3D Tiles格式 下载开源工具 在github上其实有好多这种工具,每个工具的用法大同小异,这…...
【易售小程序项目】小程序首页完善(滑到底部数据翻页、回到顶端、基于回溯算法的两列数据高宽比平衡)【后端基于若依管理系统开发】
文章目录 说明细节一:首页滑动到底部,需要查询下一页的商品界面预览页面实现 细节二:当页面滑动到下方,出现一个回到顶端的悬浮按钮细节三:商品分列说明优化前后效果对比使用回溯算法实现ControllerService回溯算法 优…...
素数求原根
1 模m原根的定义 1.1符号说明: Z m ∗ Z_m^* Zm∗:代表满足 1 < i < m − 1 , ( i , m ) 1 1<i<m-1,(i,m)1 1<i<m−1,(i,m)1的数字 i i i组成的集合 o r d m ( a ) ord_m(a) ordm(a):代表 a ( m o d m ) a(mod m) a(modm)在 Z m ∗ Z_m^* Zm∗中的…...
【Apollo学习笔记】——规划模块TASK之PATH_ASSESSMENT_DECIDER
文章目录 前言PATH_ASSESSMENT_DECIDER功能简介PATH_ASSESSMENT_DECIDER相关信息PATH_ASSESSMENT_DECIDER总体流程1. 去除无效路径2. 分析并加入重要信息给speed决策SetPathInfoSetPathPointType 3. 排序选择最优的路径4. 更新必要的信息 前言 在Apollo星火计划学习笔记——Ap…...
09 mysql fetchSize 所影响的服务器和客户端的交互
前言 这是一个 之前使用 spark 的时候 记一次 spark 读取大数据表 OOM OutOfMemoryError: GC overhead limit exceeded 因为一个 OOM 的问题, 当时使用了 fetchSize 的参数 应用服务 hang 住, 导致服务 503 Service Unavailable 在这个问题的地方, 出现了一个查询 32w 的数据…...
DevEco Studio 配置
首先,打开deveco studio 进入首页 …我知道你们想说什么,我也想说 汉化配置 没办法,老样子,先汉化吧,毕竟母语看起来舒服 首先,点击软件左下角的configure,在配置菜单里选择plugins 进入到插件页面, 输入chinese,找到汉化插件,(有一说一写到这我心里真是很不舒服) 然后点击o…...
Nginx自动探活后端服务状态自动转发,nginx_upstream_check_module的使用
一、三种方案 nginx对后端节点健康检查的方式主要有3种 1. gx_http_proxy_module 模块和ngx_http_upstream_module模块(自带) 官网地址:http://nginx.org/cn/docs/http/ng … proxy_next_upstream 严格来说,nginx自带是没有针对负载均衡后端节点的健康检查的,但是可以通…...
CSS 一个好玩的卡片“开卡效果”
文章目录 一、用到的一些CSS技术二、实现效果三、代码 一、用到的一些CSS技术 渐变 conic-gradientbox-shadowclip-path变换、过渡 transform、transition动画 animation keyframes伪类、伪元素 :hover、::before、::after …绝对布局。。。 clip-path 生成网站 https://techb…...
lintcode 667 · 最长的回文序列【中等 递归到动态规划】
题目 https://www.lintcode.com/problem/667/ 给一字符串 s, 找出在 s 中的最长回文子序列的长度. 你可以假设 s 的最大长度为 1000.样例 样例1输入: "bbbab" 输出: 4 解释: 一个可能的最长回文序列为 "bbbb" 样例2输入…...
oracle sql语言模糊查询
在Where子句中,可以对datetime、char、varchar字段类型的列用Like子句配合通配符选取那些“很像...”的数据记录,以下是可使用的通配符: % 零或者多个字符 _ 单一任何字符(下划线) / 特殊字符 [] 在某一范…...
【Ubuntu】解决ubuntu虚拟机和物理机之间复制粘贴问题(无需桌面工具)
解决Ubuntu虚拟机和物理机之间复制粘贴问题 第一步 先删除原来的vmware tools(如果有的话) sudo apt-get autoremove open-vm-tools第二步 安装软件包,一般都是用的desktop版本(如果是server换一下) sudo apt-get …...
解决ubuntu文件系统变成只读的方法
所欲文件变成只读,这种情况一般是程序执行发生错误,磁盘的一种保护措施 使用fsck修复 方法一: # 切换root sudo su # 修复磁盘错误 fsck -t ext4 -v /dev/sdb6 方法二: fsck.ext4 -y /dev/sdb6 重新用读写挂载 上面两种方法&…...
高数刷题笔记
常见等价无穷小 注意讨论 第二个等价无穷小 夹逼定理!!! 递归数列可以尝试用关系式法 通常用到夹逼定理的时候都会用到放缩构造出一大一小两个函数,将原函数夹在中间,然后使得两端函数极限相同则可推出原函数的极限&am…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
