You can use filters to modify the header or the content of a servlet request or response. Within a Web application, you can define many filters, and a single filter can act on one or more servlets or JavaServer Pages (JSPs). Filters can help you accomplish a number of tasks, including data authentication, logging, and encryption.
You can map filters to a URL or a servlet name. When a filter is mapped to a URL (path-mapped), the filter applies to every servlet and JSP in the Web application. When a filter is mapped to a servlet name (servlet-mapped), it applies to a single servlet or JSP. EAServer constructs a list of the filters declared in a Web application’s deployment descriptor; this list is called a filter chain. The order of the filters in the filter chain determines the order in which the filters are executed. EAServer constructs the filter chain by first adding the path-mapped filters, in the order in which they are declared in the deployment descriptor, then adding the servlet-mapped filters in the order in which they appear in the deployment descriptor. As a result, the path-mapped filters are executed first, followed by the servlet-mapped filters.
This sample declares the path-mapped filter, MyFilter:
<filter> <filter-name> MyFilter </filter-name> <filter-class> MyFilter </filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> <filter-mapping>
Use the Web Management Console to add a new filter to a Web application and map it to either a servlet name or a URL pattern.
Adding
a new filter to a Web application
Create a filter using a J2EE development tool.
Redeploy the WAR file (see the deploy command, described in Chapter 12, “Command Line Tools,” of the EAServer System Administration Guide), or “Deploying Web applications”.
The settings for the filter are maintained in the web.xml file. You can add filters at the request dispatcher level. “Filter mapping properties” describes how to map a Web application filter.
Servlet filters must implement the javax.servlet.Filter interface and define these methods:
Interface method |
Description |
---|---|
init |
Calls a filter into service and sets the filter’s configuration object |
doFilter |
Performs the filtering work |
getFilterConfig |
Returns the filter’s configuration object |
destroy |
Removes a filter from service |
To initialize each filter, EAServer calls the init method and passes in a FilterConfig object, which provides the filter with access to the Web application’s ServletContext, the initialization parameters, and the filter name. After all the filters in a chain have been initialized, EAServer calls FilterChain::doFilter for the first filter in the chain and passes it a reference to the filter chain. Subsequently, each filter passes control to the next filter in the chain by calling the doFilter method. The requested resource, servlet or JSP, is served after all the filters in the chain have been served. To halt further filter and servlet processing from within a filter, do not call doFilter. To notify a filter that it is being removed from service, EAServer calls the destroy method. Within this method, the filter should clean up any resources that it holds: memory, file handles, threads, and so on. destroy is called only once after all the threads within the filter’s doFilter method have exited.
Here is a sample implementation of a servlet filter, which records either the amount of time it takes to process the request, or the time the request finishes processing. The time is recorded using the ServletContext::log method. The filter uses the value of the initialization parameter type to determine whether to record the absolute time the filter finished, or the amount of time it took to process the request. If the value of type is “absolute,” the filter logs the time the request completes; otherwise, it logs the processing time, in milliseconds.
package filters; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.util.Date; public class TimerFilter implements Filter { private FilterConfig _filterConfig = null; /** * The server calls this method to initialize the Filter and * passes in a FilterConfig object. */ public void init (FilterConfig filterConfig) throws javax.servlet.ServletException { _filterConfig = filterConfig; } /** * Return the FilterConfig object */ public FilterConfig getFilterConfig() { return _filterConfig; } /** * EAServer calls this method each time a servlet, JSP or static Web * resource is invoked. */ public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { // This is executed before the servlet/jsp/static resource is served. long startTime = System.currentTimeMillis(); // Pass control to the next filter in the chain. chain.doFilter(request, response); // This is executed after the servlet/jsp/static resource has been served. long endTime = System.currentTimeMillis(); // Get the ServletContext from the FilterConfig ServletContext context = _filterConfig.getServletContext(); // Get the type parameter from the filter's initialization // paramters. Return null if the parameter was not set String type = (String)_filterConfig.getInitParameter("type"); // Get the filter’s name to include in the log String filterName = _filterConfig.getFilterName(); HttpServletRequest httprequest = (HttpServletRequest)request; String path = httprequest.getRequestURI(); // By default, record the absolute time if ((type == null) || (type.equals("absolute"))) { Date date = new Date(endTime); context.log(filterName + " - " + path + " finished: " + date.toString()); } else { context.log(filterName + " - time to process " + path + ": " + (endTime - startTime) + "ms"); } } /** * Notifies the filter that it is being taken out of service. */ public void destroy() { // free resources } }