Подтвердить что ты не робот

Порядок выполнения сервлет-фильтров

Я наткнулся на ошибку в своем веб-приложении, которая заставила меня почесать голову (и, в конце концов, потянув мои волосы) некоторое время, прежде чем я узнал, что происходит.

В принципе, у меня было 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.

4b9b3361

Ответ 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>

Проверьте этот для получения дополнительной информации.