Filters are a new feature in the Java servlet API for version 2.3. This chapter describes the new API classes and methods that provide a lightweight framework for filtering of Servlets and static content in the API. It describes the ways that filters can be configured in a web application, and describes some of the conventions and semantics around how they can be implemented.
Filters allow on the fly transformations of the payload and header information both of the request in to a resource and on the response from a resource.
API documentation for this model is provided in the API definitions chapters of this document. Configuration syntax for filters is given by the Document Type Definition in Chapter 13. Both should be referenced when reading this chapter.
What is a filter?
A filter is a reusable piece of code that transforms either the content of an HTTP request or response and can also modify header information. Filters differ from Servlets in that they do not themselves usually create a response, rather, they are there to modify or adapt the request for a resource and modify or adapt the response from a request for a resource within the web application.
The main functionality areas that are available to the Filter author are
• They can intercept the invocation of a servlet or static resource before the resource is invoked.
• They can look at the request for a resource before it is invoked.
• They can modify the request headers and request data by providing customized versions of the request object that wrap the real request.
• They can modify the response headers and response data by providing customized versions of the response object that wrap the real response.
• They can intercept the invocation of a resource after the it is called.
• They can be configured to act on a Servlet, on groups of Servlets or static content
• Servlets or static content can be configured to be filtered by zero, one or more filters in a specifiable order.
Examples of Filtering Components
• Authentication Filters
• Logging and Auditing Filters
• Image conversion Filters
• Data compression Filters
• Encryption Filters
• Tokenizing Filters
• Filters that trigger resource access events
• XSL/T filters that transform XML content
• Mime-type chain Filters
The main concepts in this filtering model are described in this section.
The application developer creates a filter by implementing the javax.servlet.Filter interface in the Java Servlet API and must provide a public constructor taking no arguments. The implementation class is packaged in the Web Archive along with the rest of the static content and Servlets that make up the web application. Each Filter is declared using the <filter> syntax in the deployment descriptor. A Filter or collection of Filters can be configured to be invoked by defining a number of <filter-mapping> elements in the deployment descriptor. The syntax associates the filter or group of filters with a particular Servlet. This is done by mapping a filter to a particular servlet by the servlet’s logical name, or mapping to a group of Servlets and static content resources by mapping a filter to a url pattern.
After the time when the web application containing filters is deployed, and before an incoming request for a resource in the web application causes a the container to access the resource and serve it back, the container must look through the list of filter mappings to
Chapter 6 Filtering 44 locate the list of filters that must be applied to the resource. How this list is built is described below. The container must ensure at some point in this time that, for each filter instance that is to be applied, it has instantiated a filter of the appropriate class, and called
setFilterConfig(FilterConfig config)on each filter instance in the list. The container must ensure that only one instance of a filter per <filter> declaration in the deployment descriptor is instantiated per Java Virtual Machine of the container. The container also ensures that thejavax.servlet.FilterConfiginstance that is passed in to this call has been initialized with the filter name as declared in the deployment descriptor for that filter, with the reference to the ServletContext for this web application and with the set of initialization parameters declared for the filter in the deployment descriptor. When the container receives the incoming request, it takes the first filter instance in the list and calls itsdoFilter()method, passing in theServletRequest and
ServletResponse, and a reference to theFilterChainobject it will use.
ThedoFilter()method of a Filter will typically be implemented following this or some subset of this pattern
1) It will examine the request headers
2) It may wrap the request object passed into itsdoFilter()method with a customized implementation of ServletRequest or HttpServletRequest if it wishes to modify request headers or data.
3) It may wrap the response object passed in to itsdoFilter()method with a customized implementation of ServletRequest or HttpServletRequest if it wishes to modify response headers or data.
4) It can make an invocation of the next entity in the filter chain. If this filter is the last filter in the chain that ends with the target servlet or static resource, the next entity is the next filter that was configured in the deployment descriptor, if it is not, it is the resource at the end of the chain. It does this by calling thedoFilter()method on the chain object (passing in the request and response it was called with, or the wrapped versions it may have created) Alternatively, it can choose to block the request by not making the call to invoke the next entity. In the latter case, the filter is responsible for filling out the response.
5) It may examine response headers after it has invoked the next filter in the chain. 6) Alternatively, the Filter may throw an exception to indicate an error in processing. Before the container can remove filter instances at the end of the lifetime of a web
application, it must call thesetFilterConfig() method on the Filter passing in null to indicate that the Filter is being taken out of service.
A set of initialization parameters can be associated with a filter using the init-params element in the deployment descriptor. The names and values of these parameters are available to the Filter at runtime via thegetInitParameterandgetInitParameterNames
methods on the filter’sFilterConfig. Additionally, theFilterConfigaffords access to the ServletContext of the web application for the loading of resources, for logging functionality or for storage of state in theServletContext’sattribute list.
Configuration of Filters in a Web Application
A Filter is defined in the deployment descriptor using the <filter> element. In this element, the programmer declares the
filter-name - this is used to map the filter to a servlet or URL filter-class - this is used by the container to identify the filter type init-params - the initialization parameters for a filter
and optionally can specify icons, a textual description and a display name for tool manipulation.
Once a Filter has been declared in the deployment descriptor, the assembler uses the <filter- mapping> element to define to which Servlets and static resources in the web application the Filter is to be applied. Filters can be associated with a Servlet by using the <servlet-name> style
<filter-name>Image Filter</filter-name> <servlet-name>ImageServlet</servlet-name> </filter-mapping>
In this case the Image Filter is applied to the Servlet with servlet-name ‘Image Servlet’.
Filters can be associated with groups of Servlets and static content using the <url-pattern> style of filter mapping:-
Chapter 6 Filtering 46 <url-pattern>/*</url-pattern>
In this case, the Logging Filter is applied to all the Servlets and static content pages in the web application, because every request URI matches the ‘/*’ URL pattern.
When processing a filter-mapping element using the url-pattern style, the container must determine whether the URL pattern matches the request URI using the path mapping rules defined in 12.1.
The order in which the container builds the chain of filters to be applied for a particular request URI is
1) The URL pattern matching filter-mappings in the same as the order that those elements appear in the deployment descriptor, and then
2) The servlet-name matching filter-mappings in the same as the order that those elements appear in the deployment descriptor