过滤器链调用如何工作?

Posted

技术标签:

【中文标题】过滤器链调用如何工作?【英文标题】:How filter chain invocation works? 【发布时间】:2014-10-01 13:00:30 【问题描述】:

我正在尝试理解过滤器链接。如this question中定义的那样

所有过滤器都是链接的(按照它们在 web.xml 中的定义顺序)。 chain.doFilter() 正在处理链中的下一个元素。 链的最后一个元素是目标资源/servlet。

我很想知道容器中容器如何处理过滤器链接的幕后情况。有人可以解释一下过滤器链接是如何在容器内处理的吗?

【问题讨论】:

【参考方案1】:

每个过滤器都实现了javax.servlet.Filter 接口,其中包括一个doFilter() 方法,该方法将requestresponse pair along with a filter chain 作为一个类的实例(由servlet 提供)容器),它实现了javax.servlet.FilterChain 接口。过滤器链反映过滤器的顺序。 The servlet container,根据web.xml文件中的配置顺序,为任何servlet或其他映射了filters的资源构造filters链。对于链中的每个过滤器,传递给它的过滤器链对象表示要调用的剩余过滤器,依次是目标servlet。

filters为例,该机制的关键步骤如下:

1. 请求目标servletcontainer 检测到有两个filters 并创建filter chain

2.链中的第一个filter 由其doFilter() 方法调用。

3.第一个filter 完成任何预处理,然后调用filter chaindoFilter() 方法。这导致第二个filter 被其doFilter() 方法调用。

4.第二个filter 完成任何预处理,然后调用filter chaindoFilter() 方法。这导致目标servlet 被其service() 方法调用。

5.当目标servlet完成后,第二个filter中的doFilter()链调用返回,第二个filter可以做任何后处理。

6.当第二个filter完成后,第一个filter中的doFilter()链调用返回,第一个filter可以做任何后处理。

7.当第一个filter完成时,执行完成。

过滤器可以插入 servlet 和 servlet 容器之间,以包装和预处理请求或包装和后处理响应。没有一个过滤器知道它们的顺序。排序完全通过过滤器链处理,根据在 web.xml 中配置过滤器的顺序

【讨论】:

以上是关于过滤器链调用如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

过滤器链调用原理

Spring Security Reactive WebFilterChainProxy 仅调用单个过滤器链

SpringSecurity工作原理概要

Spark 过滤器未按预期工作。“列”对象不可调用

SpringSecurity是如何玩弄过滤器链的

SpringSecurity是如何玩弄过滤器链的