我偶然发现我的网络应用程序中的一个错误,让我摸不着头脑(并最终拉了我的头发)一段时间才发现发生了什么。
基本上,我在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应用程序部署描述符中。
(来自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的故障?是否在某处提供了文档,我应该提交错误报告吗?
我在Java 7中使用Tomcat 7.0.39。
答案 0 :(得分:44)
当容器重新收到请求时,它首先会找到所有与<url-pattern>
匹配的请求URI的过滤器映射。这成为过滤器链中的第一组过滤器。接下来,它找到所有与<servlet-name>
匹配的过滤器映射,并与请求URI匹配。这成为过滤器链中的第二组过滤器。在这两个过滤器中,过滤器按照它们在D.D中声明的顺序执行。
根据specs
容器用于构建要应用于的过滤器链的顺序 特定请求URI如下:
- 首先,
<url-pattern>
匹配过滤器的映射顺序与这些相同 元素出现在部署描述符中。- 接下来,
醇><servlet-name>
匹配过滤器的映射顺序与这些相同 元素出现在部署描述符中。
答案 1 :(得分:-6)
此外,您还可以定义应用过滤器的顺序。这可以通过在web.xml中添加以下行来完成:
<absolute-ordering>
<name>encodingFilter</name>
<name>SpringFormMethodFilter</name>
</absolute-ordering>
查看this以获取更多信息。