Home > Articles > Programming > Java

Java Reference Guide

Hosted by

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Servlet Filters

Last updated Mar 14, 2003.

One of the best features added to the Servlet 2.3 specification was support for Servlet Filters. A filter is an object that can transform a request or modify a response. Note that filters are not Servlets and they are not responsible for creating a response. They are preprocessors of requests before they reach a Servlet and postprocessors of responses after leaving a Servlet. Servlet filters can:

  • Intercept a Servlet's invocation before the Servlet is called

  • Examine a request before the destination Servlet is invoked

  • Modify request headers and request data by subclassing the HttpServletRequest object and wrapping the original request

  • Modify the response headers and response data by subclassing the HttpServletResponse object and wrapping the original response

  • Intercept a Servlet's invocation after the servlet is called

The designers of Servlet Filters identified the following examples for their use:

  1. Authentication Filters

  2. Logging and Auditing Filters

  3. Image conversion Filters

  4. Data compression Filters

  5. Encryption Filters

  6. Tokenizing Filters

  7. Filters that trigger resource access events

  8. XSL/T filters

  9. Mime-type chain Filter

Servlet filters are classes that implement the javax.servlet.Filter interface. This interface has three methods:

public interface Filter {
  public void init(FilterConfig filterConfig);
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain);
  public void destroy();
}

Where its methods have the following functionality:

  • init(): called when the filter is initialized and loaded into memory by the Servlet container; called when the filter is being put into service

  • doFilter(): called by the Servlet container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain. The FilterChain passed in to this method allows the Filter to pass on the request and response to the next entity in the chain

  • destroy(): called just prior to the filter being removed from memory; called when the filter is being taken out of service

When you filter’s doFilter method is invoked, you choose whether you want to perform functionality before the rest of the chain is executed (or in our simple example: before the Servlet is invoked) and/or after the rest of the chain is executed. Calling the FilterChain’s doFilter() method causes the other filters or Servlets that are handling a request to be invoked. You can call the doFilter() method at any time in your doFilter() implementation.

As an example, let's look at a simple filter that records the response time of our HelloServlet (see the beginning of Java Web Technologies.) We will not touch the HelloServlet code. Instead, we will create a filter class and then modify the web deployment descriptor to tell the Servlet container to pass all requests through our Servlet. Listing 1 shows the code for our TimerFilter class.

Listing 1. TimerFilter

package com.informit.webtechnologies;

import javax.servlet.*;

public class TimerFilter implements Filter
{
   private FilterConfig config;

   public void init(FilterConfig filterConfig) throws ServletException
   {
      this.config = filterConfig;
   }

   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
              throws java.io.IOException, ServletException
   {
      // Record the start time of the request
      long before = System.currentTimeMillis();

      // Invoke the Servlet
      chain.doFilter( req, res );

      // Capture the end time of the request
      long after = System.currentTimeMillis();
 
      // Display the elapsed time to the standard output
      System.out.println("Elapsed Time: " + ( after - before ) + "ms" );   
   }

   public void destroy()
   {
      this.config = null;
   }
}

The focus of the TimerFilter class is the doFilter() method; the init and destroy methods manage an internal FilterConfig member variable that is not used in this example. The doFilter() method records the start time that the filter is invoked, executes the rest of the filter chain, and then captures the end time of the request to display the elapsed time to the standard output.

The functionality of this filter is simple, but how do we hook it up to intercept Servlets? The answer is by modifying the web deployment descriptor. In the Servlet 2.3 specification, the following two sections were added to web deployment descriptor that parallel the Servlet descriptors:

  • filter: defines a unique filter name and the fully qualified class name that it references

  • filter-mapping: maps URLs to filters

So in this example we add the following to the beginning of the web.xml file:

<filter>
  <filter-name>TimerFilter</filter-name>
  <filter-class>com.informit.webtechnologies.TimerFilter</filter-class>
</filter>

<filter-mapping> <filter-name>TimerFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

This defines a TimerFilter as being implemented by the com.informit.webtechnologies.TimerFilter class and matching all URLs in our web application (by matching the URL pattern “/*”.) So the complete web.xml file is shown in listing 2.

Listing 2. Filter example’s web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                            "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">

<web-app>
  <filter>
    <filter-name>TimerFilter</filter-name>
    <filter-class>com.informit.webtechnologies.TimerFilter</filter-class>
  <filter-mapping>

  <filter-mapping>
    <filter-name>TimerFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <servlet>
    <servlet-name>MyHelloServlet</servlet-name>
    <servlet-class>HelloServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>MyHelloServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

Build your WAR file as usual and drop the TimerFilter.class file in the /WEB-INF/classes/com/informit/webtechnologies directory. Deploy your WAR file to your Servlet container, and then watch the output. The following is sample output when deploying this WAR file to Jetty running inside JBoss:

00:49:57,382 INFO [STDOUT] Elapsed Time: 10ms
00:49:57,382 INFO [STDOUT] Elapsed Time: 0ms
00:49:57,382 INFO [STDOUT] Elapsed Time: 0ms
00:49:57,382 INFO [STDOUT] Elapsed Time: 10ms
00:49:57,382 INFO [STDOUT] Elapsed Time: 0ms
00:49:57,382 INFO [STDOUT] Elapsed Time: 10ms

Summary

This has been a brief introduction to using Servlet Filters. You can define multiple filters for the same URLs to accomplish tasks such asadding additional logging, implementing authentication and security, and timing requests, just to name a few. In an advanced implementation of filters you might perform XSLT or other transformations to convert content generated in your Servlet for presentation to specific output devices (such as mobile devices.) I hope this will inspire you to experiment with filters and pick up a good book on Servlets that will take you further.