Filter sind im DD deklarierte und vom Container verwaltete Instanzen des Interfaces javax.servlet.Filter. Es gibt drei Methoden, die den Lifecycle bestimmen:
doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { : // Code der etwas vor Aufruf der Kette macht : chain.doFilter(request, response); // weitere Abarbeitung im Filterstack : // Code der etwas nach Aufruf der Kette macht : }
Damit der Conainer eine Filterinstanz erzeugen kann, muss jeder Filter einen parameterlosen Konstruktor besitzen.
Im DD werden Filter deklariert und mittels Mappingregeln per URL-Pattern oder Servlet-Name bei der Abarbeitung eines Requests berücksichtigt:
// Filter deklarieren <filter> <filter-name>My cool filter</filter-name> <filter-class>foo.bar.MyFilter</filter-class> <init-param> // kann im FilterConfig abgegriffen werden <param-name>loglevel</param-name> <param-value>10</param-value> </init-param> </filter> // // Filter auf eine URL mappen <filter-mapping> <filter-name>My cool filter</filter-name> <url-pattern>*.do</url-pattern> <dispatcher>REQUEST</dispatcher> // optional, addressiert request-dispatching, auch INCLUDE, FORWARD, ERROR </filter-mapping> // // Filter auf ein Servlet mappen <filter-mapping> <filter-name>My cool filter</filter-name> <servlet-name>SomeServlet</servlet-name> </filter-mapping>
Die Reihenfolge mehrerer Filter im Filterstack bestimmt der Container nach folgenden Regeln:
Filter werden, ähnlich wie Servlets, einmal pro Webapplikation instanziiert, sie sind Webapplikation-Singletons. Die Spezifikation sagt zwar, dass per JVM eine Instanz erzeugt wird, aber das wird nicht stimmen. Dann könnte man ja Informationen zwischen verschiedenen Webanwendungen, die in der gleichen JVM laufen, austauschen. Das klingt interessant, brächte aber erhebliche konzeptionelle Probleme mit sich, von denen in der Spezifikation keine Rede ist. Filter müssen für den nebenläufigen Einsatz designed werden, mit anderen Worten, nichttriviale Filter enthalten synchronisieren Code.