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. ThedoFilter() 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 thecom.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.
Posted in: