2013-06-13 2 views
29

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

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

ответ

41

Когда контейнер recives запроса, он сначала находит все отображения фильтров с <url-pattern>, который соответствует запросу URI. Это становится первым набором фильтров в цепочке фильтров. Далее он находит все сопоставления фильтра с <servlet-name>, который соответствует URI запроса. Это становится вторым набором фильтров в цепочке фильтров. В обоих наборах фильтры выполняются в том порядке, в котором они объявлены в D.D.

Согласно specs

Порядок контейнер использует в построении цепочки фильтров, которые должны применяться для конкретного запроса URI, выглядит следующим образом:

  1. Во-первых, <url-pattern> соответствия фильтра сопоставления в том же порядке, что и элементы в дескрипторе развертывания.
  2. Далее соответствующие сопоставления фильтров <servlet-name> в том же порядке, что и элементы , отображаются в дескрипторе развертывания.
+0

Спасибо, теперь все ясно. –

-5

Кроме того, вы можете определить порядок применения фильтров. Это может быть достигнуто путем добавления следующих строк в вашем web.xml:

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

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

+8

** Это абсолютно неправильно, что внешний тег для фрагментов не фильтрует ** –

Смежные вопросы