一尘不染

Servlet过滤器的执行顺序

tomcat

我偶然发现了我的Web应用程序中的一个错误,该错误使我head了一下头(并最终拔了头发),然后才发现发生了什么情况。

基本上,我在web.xml中定义了2个过滤器,并且两个映射是这样的:

<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <servlet-name>SpringMVCDispatcher</servlet-name>
</filter-mapping>

<filter-mapping>
    <filter-name>SpringFormMethodFilter</filter-name>
    <url-pattern>/administration/*</url-pattern>
</filter-mapping>

它们都是Spring
MVC过滤器。我的问题是,尽管encodingFilter应该在其他任何机会有机会读取之前将请求编码设置为UTF-8的事实,但我获得的表单数据并未解释为UTF-8。

我终于注意到表单方法过滤器是在编码过滤器之前执行的,尽管定义过滤器映射的顺序应该是它们链接的顺序:

过滤器在链中的顺序与过滤器映射在Web应用程序部署描述符中出现的顺序相同。

(来自Oracle

当我对两个映射使用相同的映射(即,映射到servlet而不是URL模式)时,将恢复顺序,并且一切都会按预期进行:

<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <servlet-name>SpringMVCDispatcher</servlet-name>
</filter-mapping>

<filter-mapping>
    <filter-name>SpringFormMethodFilter</filter-name>
    <servlet-name>SpringMVCDispatcher</servlet-name>
</filter-mapping>

这是Servlet规范的一部分,还是Tomcat的故障?是否在某处记录了文档,我应该提交错误报告吗?

我将Tomcat 7.0.39与Java 7配合使用。


阅读 541

收藏
2020-06-16

共1个答案

一尘不染

当容器接收到请求时,它首先找到所有<url- pattern>与请求URI匹配的过滤器映射。这将成为过滤器链中的第一组过滤器。接下来,它将找到所有<servlet- name>与请求URI相匹配的过滤器映射。这将成为过滤器链中的第二个过滤器集合。在这两个集合中,过滤器均按照在部署描述符(DD)中声明的顺序执行

根据规格

容器在构建要应用于特定请求URI的过滤器链时使用的顺序如下:

  1. 首先,<url-pattern>匹配过滤器映射的顺序与这些元素在部署描述符中出现的顺序相同。
  2. 接下来,以<servlet-name>与这些元素出现在部署描述符中的顺序相同的顺序匹配过滤器映射。
2020-06-16