Servlet Filters with example
Servlet filters can:
Listing 1. TimerFilter
package com.techpage.webtechnologies;
Listing 2. Filterexample’s web.xml
<?xml version="1.0" encoding="UTF-8"?>
One of the best features added to the Servlet 2.3 specificationwas support for Servlet Filters. A filter is an object that can transform arequest or modify a response. Note that filters are not Servlets and they arenot responsible for creating a response. They are preprocessors of requestsbefore they reach a Servlet and postprocessors of responses after leaving aServlet.
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 theHttpServletRequest object and wrapping the original request
Modify the response headers and response data by subclassing theHttpServletResponse object and wrapping the original response
Intercept a Servlet's invocation after the servlet is called
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 filteris initialized and loaded into memory by the Servlet container; called when thefilter is being put into service
· doFilter(): called by the Servletcontainer each time a request/response pair is passed through the chain due toa client request for a resource at the end of the chain. The FilterChain passedin to this method allows the Filter to pass on the request and response to thenext entity in the chain
· destroy(): called just prior tothe filter being removed from memory; called when the filter is being taken outof service
When you filter’s doFilter method is invoked, you choose whether you want to performfunctionality before the rest of the chain is executed (or in our simpleexample: before the Servlet is invoked) and/or after the rest of the chain isexecuted. Calling the FilterChain’s doFilter()method causes the other filters or Servlets thatare handling a request to be invoked. You can call the doFilter() method at any time inyour doFilter() implementation.
As an example, let's look at a simple filter that records theresponse time of our HelloServlet(see the beginning ofJava Web Technologies.) We will not touch the HelloServlet code. Instead, we will create a filter class and then modifythe web deployment descriptor to tell the Servlet container to pass allrequests through our Servlet. Listing 1 shows the code for our TimerFilterclass.
Listing 1. TimerFilter
package com.techpage.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 therequest to display the elapsed time to the standard output.
The functionality of this filter is simple, but how do we hook itup to intercept Servlets? The answer is by modifying the web deploymentdescriptor. In the Servlet 2.3 specification, the following two sections wereadded to web deployment descriptor that parallel the Servlet descriptors:
· filter: defines a unique filter name and the fully qualified classname that it references
· filter-mapping: maps URLs to filters
So in this example we add the following to the beginning of theweb.xml file:
<filter> <filter-name>TimerFilter</filter-name>
<filter-class>com.techpage.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.techpage.webtechnologies.TimerFilter class and matching all URLs in our web application (bymatching the URL pattern “/*”.) So the complete web.xml file is shown inlisting 2.
Listing 2. Filterexample’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.techpage.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 filein the /WEB-INF/classes/com/techpage/webtechnologies directory. Deploy your WARfile to your Servlet container, and then watch the output. The following issample output when deploying this WAR file to Jetty running inside JBoss:
00:49:57,382 INFO [STDOUT] Elapsed Time: 10ms00: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
