Thursday, July 31, 2008

Servlet filter doesn't work, or does it ?

It has been a while I found the time to blog. Here is a little entry.

I've often hear that a Servlet filter was not working while trying to filter some Java resource. Usually this is because the filter is defined like:


<filter-mapping>
<filter-name>My Broken Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


and the filtered content is accessed through request dispatching.

This look correct, but this is not. In the 2.4 version of the Servlet spec you can now filter resources accessed directly from the request, through an include request dispatcher, through a forward request dispatch or through the error mechanism of the spec.
By default, if nothing is specified, the filter will only apply to direct requests. This is the case here and this is what confuses people.

If you want to filter request coming from an include request dispatcher you need to add: <dispatcher>INCLUDE</dispatcher>

Here are few examples:
The following will only filter direct requests:

<filter-mapping>
<filter-name>My Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


The following will only filter direct requests too:

<filter-mapping>
<filter-name>My Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>


The following will only filter direct requests and inclusions:

<filter-mapping>
<filter-name>My Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>


The following will only filter inclusions:

<filter-mapping>
<filter-name>My Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>


The following will filter all:

<filter-mapping>
<filter-name>My Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>


Want more ? Check the servlet spec, "SRV.6.2.5 Filters and the RequestDispatcher"