Jak zdefiniować kolejność wykonywania filtrów serwletów za pomocą adnotacji w WAR

167

Jeśli zdefiniujemy filtry serwletów specyficzne dla aplikacji webowych we własnym WAR web.xml, to kolejność wykonywania filtrów będzie taka sama, jak kolejność, w jakiej są zdefiniowane w pliku web.xml.

Ale jeśli zdefiniujemy te filtry za pomocą @WebFilteradnotacji, jaka jest kolejność wykonywania filtrów i jak możemy określić kolejność wykonywania?

siva636
źródło

Odpowiedzi:

187

Rzeczywiście nie można zdefiniować kolejności wykonywania filtrów za pomocą @WebFilteradnotacji. Jednak, aby zminimalizować web.xmlużycie, wystarczy dodać adnotacje do wszystkich filtrów za pomocą tylko adnotacji filterName, aby nie potrzebować <filter>definicji, a jedynie <filter-mapping>definicję w żądanej kolejności.

Na przykład,

@WebFilter(filterName="filter1")
public class Filter1 implements Filter {}

@WebFilter(filterName="filter2")
public class Filter2 implements Filter {}

w web.xmltym tylko:

<filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern>/url1/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>filter2</filter-name>
    <url-pattern>/url2/*</url-pattern>
</filter-mapping>

Jeśli chcesz zachować wzorzec adresu URL @WebFilter, możesz po prostu tak zrobić,

@WebFilter(filterName="filter1", urlPatterns="/url1/*")
public class Filter1 implements Filter {}

@WebFilter(filterName="filter2", urlPatterns="/url2/*")
public class Filter2 implements Filter {}

ale trzeba jeszcze utrzymać <url-pattern>in web.xml, ponieważ nie jest to wymagane zgodnie z XSD, choć mogą to być puste:

<filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern />
</filter-mapping>
<filter-mapping>
    <filter-name>filter2</filter-name>
    <url-pattern />
</filter-mapping>

Niezależnie od podejścia, wszystko to zawiedzie w Tomcat do wersji 7.0.28, ponieważ dusi się obecnością <filter-mapping>bez <filter>. Zobacz także Używanie Tomcata, @WebFilter nie działa z <filter-mapping> wewnątrz web.xml

BalusC
źródło
5
mogli wprowadzić orderatrybut zagnieżdżonej @WebFilterMappingadnotacji. Zastanawiam się, czy nie zrobili tego dla prostoty
Bozho
12
@Bozho: To nie byłoby wystarczająco szczegółowe. Co się stanie, jeśli Twoja aplikacja internetowa jest dostarczana z bibliotekami innych firm, które zawierają filtr? Trudno z góry określić jego kolejność.
BalusC
1
@BalusC: Coś poszło nie tak w Twoim przykładzie: wzorzec-url jest zamknięty nazwą filtra.
AndrewBourgeois
3
@AndrewBourgeois: Naprawiono. To był błąd copypaste. Szkoda, że ​​edytor Markdown nie ma wbudowanej walidacji XML, takiej jak w Eclipse;)
BalusC
6
Użycie <url-pattern />nie działa na JBoss EAP 6.1 - nadpisuje @WebFilterwartość i w ogóle uniemożliwia działanie filtra.
seanf
12

Wydaje się, że specyfikacja Servlet 3.0 nie dostarcza wskazówek, w jaki sposób kontener powinien porządkować filtry, które zostały zadeklarowane za pomocą adnotacji. Jest jednak jasne, jak zamówić filtry poprzez ich deklarację w pliku web.xml.

Bądź bezpieczny. Użyj filtrów kolejności plików web.xml, które mają wzajemne zależności. Postaraj się, aby wszystkie filtry były niezależne w kolejności, aby zminimalizować potrzebę używania pliku web.xml.

vkraemer
źródło
4
Mam w swoim projekcie wiele filtrów Servlet, z których tylko jeden konkretny filtr musi być wywołany jako pierwszy, a kolejność innych filtrów nie ma znaczenia. Czy muszę zbezcześcić wszystkie filtry w pliku web.xml? A może są jakieś skróty?
siva636