31

在我发现发生了什么之前,我偶然发现了我的 Web 应用程序中的一个错误,它让我挠了挠头(并最终拉扯了我的头发)。

基本上,我在 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 过滤器。我的问题是我得到的表单数据没有被解释为 UTF-8,尽管 encodingFilter 应该在其他任何东西有机会从中读取之前将请求编码设置为 UTF-8。

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

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

(来自甲骨文

当我使用相同的映射,即映射到 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 的故障?它是否记录在某处,我应该提交错误报告吗?

我正在使用带有 Java 7 的 Tomcat 7.0.39。

4

2 回答 2

47

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

根据规格

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

  1. 首先,<url-pattern>匹配过滤器映射的顺序与这些元素在部署描述符中出现的顺序相同。
  2. 接下来,<servlet-name>匹配过滤器映射的顺序与这些元素在部署描述符中出现的顺序相同。
于 2013-06-13T12:13:02.400 回答
-7

此外,您可以定义应用过滤器的顺序。这可以通过在 web.xml 中添加以下行来完成:

<absolute-ordering>
  <name>encodingFilter</name>
  <name>SpringFormMethodFilter</name>
</absolute-ordering>

检查以获取更多信息。

于 2013-10-24T13:54:49.830 回答