0

0

Java过滤器原理_Java Filter工作机制与生命周期原理

煙雲

煙雲

发布时间:2026-01-09 12:12:49

|

331人浏览过

|

来源于php中文网

原创

filter 由 servlet 容器在启动时扫描注册并按序调用 dofilter(),其生命周期由 init()、dofilter()、destroy() 三方法管控,且 request 流只能读一次,需用 httpservletrequestwrapper 包装实现重放。

java过滤器原理_java filter工作机制与生命周期原理

Filter 是怎么被容器调用的?

Java Web 中的 Filter 不是靠你手动 new 或调用生效的,而是由 Servlet 容器(如 Tomcat)在启动时扫描、实例化,并按配置顺序插入请求处理链。它本质是一个“拦截器”,但和 Spring 的 HandlerInterceptor 不同——Filter 在 Servlet 生命周期之外,更底层,能拦请求头、请求体、响应体,甚至跳过目标 Servlet。

  • 容器启动时读取 web.xml 或注解(@WebFilter),注册 Filter 实例到内部过滤器链
  • 每次 HTTP 请求进来,容器按声明顺序依次调用 doFilter();只有显式调用 chain.doFilter(request, response),才会继续向后传递
  • Filter 实例是单例的(每个类一个实例),但 doFilter() 方法是多线程并发执行的,所以不能在 Filter 内部用非线程安全的成员变量存请求数据

init() / doFilter() / destroy() 什么时候触发?

Filter 的生命周期由容器完全管理,三个方法的触发时机非常明确,但容易误用:

  • init():容器启动完成、Filter 实例化后立即调用一次,且仅一次。适合做一次性初始化(如加载配置、初始化连接池)。注意:FilterConfig 可从中获取 init-param,但无法拿到 ServletContext 的完整引用(需通过 config.getServletContext() 获取)
  • doFilter():每次匹配请求都会调用,参数是包装过的 ServletRequest/ServletResponse(可能是 HttpServletRequest/HttpServletResponse,但必须向下转型才可用 HTTP 特有方法)
  • destroy():容器关闭前调用一次,用于释放资源。但不要指望它一定被执行(比如 kill -9 进程就跳过)

为什么 request.getInputStream() 只能读一次?Filter 里怎么安全重放?

这是 Filter 最常踩的坑:HTTP 请求体(如 JSON)默认是流式读取,request.getInputStream()request.getReader() 调用一次后流就关闭了,后续 Servlet 拿不到原始数据。

飞书多维表格
飞书多维表格

表格形态的AI工作流搭建工具,支持批量化的AI创作与分析任务,接入DeepSeek R1满血版

下载
  • 解决方案不是“缓存字节”,而是用装饰器模式包装请求对象,例如继承 HttpServletRequestWrapper
  • 关键点:在 doFilter() 开头就把整个 body 读入内存(IOUtils.toString(request.getInputStream(), "UTF-8")),再构造一个可重复读的 HttpServletRequestWrapper 子类,重写 getInputStream()getReader() 返回新缓存
  • ⚠️ 注意:大文件上传场景下别这么干,会 OOM;生产环境建议只对特定路径(如 /api/**)或小 payload(Content-Length )启用缓存
public class BodyCachingRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] cachedBody;

    public BodyCachingRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.cachedBody = IOUtils.toByteArray(request.getInputStream());
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new CachedServletInputStream(cachedBody);
    }

    // ... 省略 getReader() 实现
}

@WebFilter 和 web.xml 配置哪个优先?

两者可以共存,但容器加载顺序有明确规定:web.xml 中定义的 Filter 总是先于 @WebFilter 注册。也就是说,如果你在 web.xml 里配了 A、B,在代码里用 @WebFilter 声明了 C,最终执行顺序是 A → B → C(前提是 URL 匹配规则一致)。

立即学习Java免费学习笔记(深入)”;

  • @WebFilter(urlPatterns = "/api/*")<url-pattern>/api/*</url-pattern> 效果等价,但注解无法设置 <dispatcher></dispatcher> 类型(如 ERROR、FORWARD),除非用 dispatcherTypes 属性显式指定
  • Tomcat 9+ 默认禁用 web.xml 的自动扫描(如果用了 metadata-complete="true"),此时 @WebFilter 是唯一方式
  • Spring Boot 项目默认不加载 web.xml,所有 Filter 必须用 @Bean 方式注册或 @WebFilter + @ServletComponentScan
Filter 的真正复杂点不在写法,而在它介入的是容器最底层的 I/O 流与线程模型。一个没考虑线程安全的成员变量、一次未 reset 的输入流、一个忘了 chain.doFilter() 的 if 分支,都可能让整个请求链静默失败。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
如何配置Tomcat环境变量
如何配置Tomcat环境变量

配置Tomcat环境变量需要在系统中添加CATALINA_HOME变量,并将Tomcat的安装路径添加到PATH变量中。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

117

2023.10.26

idea如何集成Tomcat
idea如何集成Tomcat

idea集成Tomcat的步骤:1、添加Tomcat服务器配置;2、配置项目部署;3、运行Tomcat服务器;4、访问项目;5、注意事项;6、关闭Tomcat服务器。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

173

2024.02.23

怎么查看Tomcat源代码
怎么查看Tomcat源代码

查看Tomcat源代码的步骤:1、下载Tomcat源代码;2、在IDEA中导入Tomcat源代码;3、查看源代码;4、理解Tomcat的工作原理;5、参与社区和贡献;6、注意事项;7、持续学习和更新;8、使用工具和插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

98

2024.02.23

常见的tomcat漏洞有哪些
常见的tomcat漏洞有哪些

常见的tomcat漏洞有:1、跨站脚本攻击;2、跨站请求伪造;3、目录遍历漏洞;4、缓冲区溢出漏洞;5、配置漏洞;6、第三方组件漏洞。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

170

2024.02.23

tomcat日志乱码怎么解决
tomcat日志乱码怎么解决

tomcat日志乱码的解决办法:1、修改tomcat的日志编码设置;2、检查ide的编码设置;3、检查操作系统的编码设置;4、使用过滤器处理日志;5、检查外部系统的编码设置;6、检查文件编码方式等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

158

2024.02.23

weblogic和tomcat有哪些区别
weblogic和tomcat有哪些区别

weblogic和tomcat的区别:1、功能;2、性能;3、规模;4、价格;5、安全性;6、配置和管理;7、社区支持;8、集成能力;9、升级和更新;10、可靠性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

200

2024.02.23

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

244

2024.02.23

tomcat启动闪退怎么解决
tomcat启动闪退怎么解决

tomcat启动闪退的解决办法:1、检查java环境;2、检查环境变量配置;3、检查端口被占用;4、检查配置文件编码;5、检查启动时需要的配置文件;6、检查相关文件是否丢失;7、检查防火墙和杀毒软件设置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

169

2024.02.23

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11.2万人学习

Java 教程
Java 教程

共578课时 | 81万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号