【问题标题】:How filter chain invocation works?过滤器链调用如何工作?
【发布时间】:2014-10-01 13:00:30
【问题描述】:
我正在尝试理解过滤器链接。如this question中定义的那样
所有过滤器都是链接的(按照它们在 web.xml 中的定义顺序)。
chain.doFilter() 正在处理链中的下一个元素。
链的最后一个元素是目标资源/servlet。
我很想知道容器中容器如何处理过滤器链接的幕后情况。有人可以解释一下过滤器链接是如何在容器内处理的吗?
【问题讨论】:
标签:
java
jakarta-ee
servlet-filters
【解决方案1】:
每个过滤器都实现了javax.servlet.Filter 接口,其中包括一个doFilter() 方法,该方法将request 和response pair along with a filter chain 作为一个类的实例(由servlet 提供)容器),它实现了javax.servlet.FilterChain 接口。过滤器链反映过滤器的顺序。 The servlet container,根据web.xml文件中的配置顺序,为任何servlet或其他映射了filters的资源构造filters链。对于链中的每个过滤器,传递给它的过滤器链对象表示要调用的剩余过滤器,依次是目标servlet。
以filters为例,该机制的关键步骤如下:
1. 请求目标servlet。 container 检测到有两个filters 并创建filter chain。
2.链中的第一个filter 由其doFilter() 方法调用。
3.第一个filter 完成任何预处理,然后调用filter chain 的doFilter() 方法。这导致第二个filter 被其doFilter() 方法调用。
4.第二个filter 完成任何预处理,然后调用filter chain 的doFilter() 方法。这导致目标servlet 被其service() 方法调用。
5.当目标servlet完成后,第二个filter中的doFilter()链调用返回,第二个filter可以做任何后处理。
6.当第二个filter完成后,第一个filter中的doFilter()链调用返回,第一个filter可以做任何后处理。
7.当第一个filter完成时,执行完成。
过滤器可以插入 servlet 和 servlet 容器之间,以包装和预处理请求或包装和后处理响应。没有一个过滤器知道它们的顺序。排序完全通过过滤器链处理,根据在 web.xml 中配置过滤器的顺序