拦截器和过滤器

本文旨在夯实基础以及实战加深理解,目的是更深的理解以便掌握,希望能跟着动手敲一遍,绝对受益匪浅

在本文,我会先给出两者的区别(理论知识),随后是两者各自的实操实现

文章目录

  • 拦截器和过滤器
    • 什么是过滤器和拦截器?
      • 1.过滤器
      • 2.拦截器
      • 执行整体流程
    • 拦截器和过滤器的区别
  • 实操:
      • 1.过滤器
        • 1.定义日志记录过滤器类`LogFilter`
        • 2.在主启动类上**添加注解**`@ServletComponentScan`
      • 2.拦截器
        • 1.创建拦截器
        • 2.注册拦截器
        • 测试
    • 好了,你学会没?

什么是过滤器和拦截器?

1.过滤器

首先说下什么是过滤器?

  1. Java Servlet规范中定义的标准,是Servlet一部分,
  2. 配置也是非常简单,直接实现javax.servlet.Filter接口就可以,
  3. 也可以用注解@WebFilter对特定的URL拦截

2.拦截器

那拦截器又是什么东东?

  1. Spring框架自身提供的组件,也就是说必须依赖SpringMvc框架才能使用,是位于Spring上下文之中
  2. AOP的一种实现,支持链式调用,通过类HandlerInterceptor实现多个拦截
  3. 说白了:就是切面编程典型实现,允许程序猿在一些核心业务操作执行的前后插入自定义的逻辑代码,如日志记录,权限认证等,而无需修改核心代码的本身

执行整体流程

我们首先看下过滤器和拦截器在整个流程中的执行顺序

请求进入
preHandle
调用Controller
返回ModelAndView
postHandle/afterCompletion
返回响应
响应返回
HTTP Request
Tomcat 容器
Filter 链
DispatcherServlet
Interceptor 链
Controller
HTTP Response

解释说明:(结合上图)

  1. Filter 开始HTTP 请求进入 Tomcat 容器。
  2. Filter 链处理:请求会经过所有配置的 FilterdoFilter() 方法。
  3. 进入 Spring MVC:请求到达 DispatcherServlet(Spring MVC 的核心控制器)。
  4. Interceptor 开始DispatcherServlet 分发请求前,会先执行拦截器链的 preHandle 方法。
  5. Controller 执行:如果 preHandle 返回 true,请求被分发到对应的 Controller 方法执行。
  6. Interceptor 后处理
    • Controller 执行完毕后,返回 ModelAndView,然后执行拦截器链的 postHandle 方法。
    • 视图渲染完毕后(或请求处理完成后),执行拦截器链的 afterCompletion 方法。
  7. Filter 结束:响应最终再次经过 Filter 链的 doFilter() 方法(反向),返回给客户端。

拦截器和过滤器的区别

特性过滤器 (Filter)拦截器 (Interceptor)
归属与依赖Servlet 规范,不依赖 SpringSpring 框架 的组件
作用范围作用于所有进入容器的请求(包括静态资源,如 /css/, /js/只作用于 Spring MVC 处理的请求(即 Controller 的请求,通常不会拦截静态资源)
实现原理基于 函数回调 (doFilter())基于 Java 反射和动态代理
使用方式web.xml 中配置或使用 @WebFilter 注解在 Spring MVC 配置中注册 (WebMvcConfigurer)
获取 IOC 容器无法 直接获取 Spring 的 IOC 容器和其中的 Bean可以,因为它本身就是 Spring 管理的,可以轻松使用 @Autowired 注入其他 Bean
执行时机/位置最早。 1. 在请求进入 Tomcat 等容器之后 2. 在进入 Servlet 之前 3. 在 Servlet 处理完之后,返回给客户端之前较晚。 1. 在请求进入 DispatcherServlet 之后 2. 在进入 Controller 之前 (preHandle) 3. 在 Controller 执行之后,视图渲染之前 (postHandle) 4. 在整个请求结束之后 (afterCompletion)
功能侧重更底层,关注的是请求本身(Request/Response),功能强大。 例如:字符编码设置、权限校验(粗粒度)、日志记录、性能监控、解压/gzip压缩。更上层,关注的是 Controller 的方法执行,与业务结合更紧密。 例如:更精细的权限校验(判断Token、角色)、日志记录(记录Controller方法、参数)、参数预处理、Controller 执行时间计算。

实操:

1.过滤器

案例:Springboot中实现日志记录过滤器

1.定义日志记录过滤器类LogFilter

主要的三大核心方法:(可以结合上面的整体执行流程图来看)

  • init() :该方法在容器启动初始化过滤器时被调用,在 Filter 的整个生命周期只会被调用一次注意:这个方法必须执行成功,否则过滤器不生效,没有作用。
  • doFilter() :容器中的每一次请求都会调用该方法, FilterChain 用来调用下一个过滤器 Filter
  • destroy(): 当容器销毁 过滤器实例时调用该方法,一般在方法中销毁或关闭资源,在过滤器 Filter 的整个生命周期也只会被调用一次
package com.zhengqian.test01aop.filter;import lombok.extern.slf4j.Slf4j;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** 日志过滤器: * @author zhengqian* @since 2025年09月04日 14:56*/
@WebFilter(urlPatterns = "/*")//过滤所有的请求
@Slf4j
public class LogFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);//初始化执行log.info("***^^^日志过滤器初始化完成");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//记录请求的开始时间long startTime = System.currentTimeMillis();//转换为HttpServletRequest获取更多信息HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;//获取基本信息String requestURI = httpServletRequest.getRequestURI();String method = httpServletRequest.getMethod();String remoteAddr = httpServletRequest.getRemoteAddr();//log.info("请求开始=> 方法:{} 路径: {}} IP:{}",method,requestURI,remoteAddr);try {filterChain.doFilter(servletRequest,servletResponse);} finally {//计算处理耗时long duration = System.currentTimeMillis() - startTime;//响应日志log.info("请求结束 ==> 路径: {} 耗时:{}",requestURI,duration);}}@Overridepublic void destroy() {Filter.super.destroy();log.info("日志过滤器销毁");}
}
2.在主启动类上添加注解@ServletComponentScan

在这里插入图片描述

OK!这个时候你启动就可以看到此过滤器成功!

你可能会问?这么简单?对的,就是这么简单!前提你要跟着做!哈哈哈!

在这里插入图片描述

2.拦截器

1.创建拦截器

核心方法解释:

  • preHandle()
    • 此方法在请求处理之前进行调用。
    • 注意:如果该方法的返回值为false ,将视为当前请求结束,不仅自身拦截器会失效,还会导致其他的拦截器也不再执行
  • postHandle()
    • 只有在 preHandle() 方法返回值为true才会执行
    • 会在Controller 中的方法调用之后,DispatcherServlet 返回渲染视图之前被调用。
  • afterCompletion():只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。
package com.zhengqian.test01aop.interceptor;import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 自定义拦截器的实现* @author zhengqian* @since 2025年09月04日 15:13*/
@Slf4j
public class CustomInterceptor implements HandlerInterceptor {/*** 请求处理前被调用* @param request 请求* @param response 响应* @param handler 处理器* @return  aa* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//添加校验权限log.info("开始出发拦截器校验前的处理------------->");return true;}/*** **其中**:`postHandle()` 方法被调用的顺序跟 `preHandle()` 是**相反**的,先声明的拦截器  `preHandle()` 方法先执行,而`postHandle()`方法反而会后执行。* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("只有在 preHandle() 方法返回值为true 时才会执行");HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("整个请求结束之后被调用");HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}}
2.注册拦截器

addPathPatterns:需要拦截的路径

excludePathPatterns: 不需要拦截的路径

package com.zhengqian.test01aop.config;import com.zhengqian.test01aop.interceptor.CustomInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author zhengqian* @since 2025年09月04日 15:19*/
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册拦截器并设置拦截路径registry.addInterceptor(new CustomInterceptor())//拦截所有.addPathPatterns("/**")//排除*/login的登录路径.excludePathPatterns("/aop/login");}
}
测试

我们建一个测试类,来进行上面的拦截测试

package com.zhengqian.test01aop.controller;import com.zhengqian.test01aop.service.TestService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** @author zhengqian* @date 2025年07月21日 16:40*/
@RestController
@RequestMapping("/aop")
public class TestController {@ResourceTestService testService;@GetMapping("/test")public  String test(){testService.test();return "测试成功!----";}@GetMapping("/login")public  String login(){testService.test();return "测试成功!----";}
}

打印日志:

1.走拦截器

在这里插入图片描述
在这里插入图片描述

好了,你学会没?

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921224.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921224.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921224.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTB 赛季8靶场 - Guardian

各位好,最近我的kali崩掉了,崩掉了,建议大家避K 番茄C盘瘦身,这家伙修改了我的avrt.dll文件,导致virtualbox不接受我的avrt.dll文件的签名了,从而导致virtualbox的虚拟机环境全崩无法开机。弄了几天&#x…

Rust+slint实现一个登录demo

系列文章目录 文章目录系列文章目录前言一、为什么前端选择slint而不是Tauri或者其他GUI框架二、开发工具三、代码编写项目结构前端代码编写后端开发编写运行效果总结前言 本文章就是一个简单rust全栈编程的一个小小的示例供rust新手阅读学习。 一、为什么前端选择slint而不是…

2025前端面试题及答案(详细)

HTML5 的新特性有哪些?简约版本:“HTML5 新特性主要体现在六个方面: 第一,语义化标签,比如 header、footer、nav 等,让页面结构更清晰; 第二,表单增强,新增了 date、emai…

分词器详解(二)

🔍 第2层:中等深度(15分钟理解) 1. 理论基础 1.1 BPE的数学原理 核心思想:通过迭代合并高频字符对构建词汇表 算法形式化: 初始化词汇表 V0{c1,c2,...,cn}V_0 \{c_1, c_2, ..., c_n\}V0​{c1​,c2​,...,c…

嵌入式学习 51单片机(3)

UART 概述通用异步收发器(UART)是一种全双工、串行、异步通信协议,常用于设备间数据传输。包含两根信号线:RXD(接收信号线)TXD(发送信号线)通信方式单工通信方向固定,仅支…

Redis AOF 持久化:银行的 “交易流水单” 管理逻辑

目录 一、AOF 的核心逻辑:“每笔交易都记流水” 二、AOF 的三个步骤:从 “临时记录” 到 “正式归档” 1. 命令追加:记到 “临时小本本” 2. 写入与同步:抄到 “正式流水册” 3. AOF 还原:拿 “流水册” 重放交易…

代码随想录训练营第三十天|LeetCode452.用最少数量的箭引爆气球、LeetCode435.无重叠空间、LeetCode763.划分字母空间

452.用最少数量的箭引爆气球 贪心算法 重合最多的气球射一箭,就是局部用箭数量最少的,全局的用箭数量就是最少的。 首先对二维数组进行排序,这样就可以让气球更加紧凑。 思路:当前气球是否和上一个气球区间重合,如…

数据库事务隔离级别与 MVCC 机制详解

最近在准备面试,正把平时积累的笔记、项目中遇到的问题与解决方案、对核心原理的理解,以及高频业务场景的应对策略系统梳理一遍,既能加深记忆,也能让知识体系更扎实,供大家参考,欢迎讨论。在数据库并发操作…

【Cursor-Gpt-5-high】StackCube-v1 任务训练结果不稳定性的分析

1. Prompt 我是机器人RL方向的博士生正在学习ManiSkill,在学习时我尝试使用相同命令训练同一个任务,但是我发现最终的 success_once 指标并不是相同的,我感到十分焦虑, 我使用的命令如下: python sac.py --env_id"…

文档权限设置不合理会带来哪些问题

文档权限设置不合理会导致信息泄露、合规风险、协作效率下降、责任难以追溯、知识资产流失、员工信任受损、管理成本增加、企业战略受阻。这些问题不仅影响日常运营,更会对企业的长远发展构成威胁。根据IBM《2024数据泄露成本报告》,全球企业因数据泄露的…

Linux网络服务——基础设置

网络服务命令1.ping命令作用:测试网络连通性(使用icmp协议)常见选项:-c:指定ping的次数,默认无限次-I:指定发送请求的网卡[rootlocalhost ~]# ping 192.168.77.78 -c 4 -I ens160 PING 192.168.…

【multisim汽车尾灯设计】2022-12-1

缘由multisim汽车尾灯设计-学习和成长-CSDN问答 为什么模仿别人做的运行没啥效果,啥也看不明白,数字电子技术要做的任务。

Langchain在调用 LLM 时统计 Token 消耗

关键点解析使用上下文管理器with get_openai_callback() as cb:这一行是核心。cb 会自动收集本次调用的 prompt tokens、completion tokens 以及 total tokens。自动统计在上下文退出时,cb 中已经包含了这次调用的消耗情况,无需额外手动计算。累加到全局…

漫谈《数字图像处理》之实时美颜技术

随着移动拍摄、直播、短视频等场景的普及,用户对 “自然、流畅、可控” 的美颜效果需求日益提升 —— 既要消除皮肤瑕疵、优化面部形态,又需避免 “过度磨皮显假”“变形失真”“实时卡顿” 等问题。实时美颜技术的核心并非单一算法的堆砌,而…

MATLAB基于PSO(粒子群算法)优化BP神经网络和NSGA-II(非支配排序遗传算法)多目标优化

代码实现了一个智能算法优化BP神经网络并进行多目标优化的完整流程,结合了PSO(粒子群算法)优化BP神经网络和NSGA-II(非支配排序遗传算法)多目标优化,用于多输入多输出的回归预测问题。 ✅ 一、主要功能 数…

白平衡分块统计数据为什么需要向下采样?

在白平衡处理中,分块统计数据时引入**向下采样(Downsampling)**,核心目标是在保证统计有效性的前提下,解决“计算效率”与“统计鲁棒性”的矛盾,同时避免局部噪声对白平衡判断的干扰。要理解这一设计的必要…

Deathnote: 1靶场渗透

Deathnote: 1 来自 <Deathnote: 1 ~ VulnHub> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.128&#xff0c;靶场IP192.168.23.129 3&#xff0c;对靶机进行端口…

windows系统服务器测试部署springboot+vue+mysql项目

1. 后端Java应用启动 直接使用命令行启动&#xff08;推荐用于测试&#xff09;&#xff1a; cd C:\Users\Administrator\Desktop\toolset\backed java -jar -Dspring.profiles.activeprod -Dserver.port8083 admin.jar2. 前端静态文件服务 由于你已经有了dist目录&#xff0c;…

Java 与 Docker 的最佳实践

在云原生时代&#xff0c;Docker 已成为应用交付和运行的事实标准。Java 作为企业级开发的主力语言&#xff0c;也需要与容器技术深度结合。然而&#xff0c;Java 程序天然有 JVM 内存管理、启动速度、镜像体积 等特点&#xff0c;如果不做优化&#xff0c;可能导致性能下降甚至…

大数据工程师认证推荐项目:基于Spark+Django的学生创业分析可视化系统技术价值解析

&#x1f496;&#x1f496;作者&#xff1a;计算机编程小央姐 &#x1f499;&#x1f499;个人简介&#xff1a;曾长期从事计算机专业培训教学&#xff0c;本人也热爱上课教学&#xff0c;语言擅长Java、微信小程序、Python、Golang、安卓Android等&#xff0c;开发项目包括大…