Порядок выполнения сервлет-фильтров
Я наткнулся на ошибку в своем веб-приложении, которая заставила меня почесать голову (и, в конце концов, потянув мои волосы) некоторое время, прежде чем я узнал, что происходит.
В принципе, у меня было 2 фильтра, определенных в моем web.xml, и два таких сопоставления:
<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, прежде чем что-либо еще сможет ее прочитать.
Наконец, я заметил, что фильтр формы был выполнен перед фильтром кодирования, хотя порядок, в котором определены отображения фильтра, должен быть порядком, в котором они связаны:
Порядок фильтров в цепочке такой же, как порядок, который сопоставления фильтров отображаются в дескрипторе развертывания веб-приложения.
(из Oracle)
Когда я использовал одно и то же отображение, то есть сопоставление с сервлетом вместо шаблона 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.
Ответы
Ответ 1
Когда контейнер возвращает запрос, он сначала находит все сопоставления фильтра с <url-pattern>
, которые соответствуют URI запроса. Это становится первым набором фильтров в цепочке фильтров. Далее он находит все сопоставления фильтра с <servlet-name>
, которые соответствуют URI запроса. Это становится вторым набором фильтров в цепочке фильтров. В обоих наборах фильтры выполняются в том порядке, в котором они объявлены в D.D.
В соответствии с спецификациями
Порядок, используемый контейнером при создании цепочки фильтров для применения к конкретный URI запроса выглядит следующим образом:
- Во-первых, сопоставление фильтров
<url-pattern>
в том же порядке, что и эти элементы появляются в дескрипторе развертывания. - Далее, сопоставление фильтров
<servlet-name>
в том же порядке, что и эти элементы появляются в дескрипторе развертывания.
Ответ 2
Кроме того, вы можете определить порядок, в котором применяются фильтры. Это можно сделать, добавив следующие строки в ваш web.xml:
<absolute-ordering>
<name>encodingFilter</name>
<name>SpringFormMethodFilter</name>
</absolute-ordering>
Проверьте этот для получения дополнительной информации.