Understanding the Filter interface

All filters implement the javax.servlet.Filter interface. The filter API has three methods that must be overridden. The following table describes these methods :
Method
Description
void init(FilterConfig config)
JRun calls the init method once to initialize the filter. Subsequent calls to the filter do not invoke the init method unless the server is restarted. This method defines the FilterConfig object, where you might access initialization parameters.
void doFilter(
�ServletRequest req,
�ServletResponse resp,
�FilterChain chain
)
Most of the work is done in the doFilter method. In doFilter, the request and response objects are acted upon and one or more filters are invoked. Regardless of the number of filters that you use, they are said to be part of the filter chain, an object that filters use to pass control to the next filter or pass control to the target resource.
The doFilter method can examine and modify the data and headers of the request and response objects.
This method uses the FilterChain object to invoke the next filter in the chain. After doing so, it can again examine and modify the data and headers of the request and response.
void destroy()
JRun calls the destroy method once, usually when shutting down, to indicate that the filter is no longer required. The destroy method typically releases resources used by the filter by destroying the FilterConfig object.

Simple filter example

The following code shows the three methods that filters must override. This example only invokes the filter chain:

import javax.servlet.*;
public class SimpleFilter implements Filter {
�public void init(FilterConfig filterConfig) {
��this.filterConfig = filterConfig;
�}
�public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
  throws java.io.IOException, javax.servlet.ServletException {
��chain.doFilter(request,response);
�}
�public void destroy() {
��this.filterConfig = null;
�}
}

Understanding the FilterConfig object

JRun initializes the filter using the FilterConfig object. The FilterConfig object provides the following methods that let you access the initialization parameters and the ServletContext object:

You define the FilterConfig object in the filter's init method. Then you can use initialization parameters established in the init method in the doFilter method.

private FilterConfig filterConfig = null;
private String version;
public void init(FilterConfig filterConfig) {
�this.filterConfig = filterConfig;
�this.version = filterConfig.getInitParameter("version");
�System.out.println("Filter initialized: " + filterConfig.getFilterName() + "version " 
  + filterConfig.getInitParameter("version"));
�}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
 throws java.io.IOException, javax.servlet.ServletException {
�version = getVersion(request);
�chain.doFilter(request,response);
}
public String getVersion(ServletRequest request) {
�return this.version;
}

In the web.xml deployment descriptor, you define the filter's initialization parameters in the Filter definition. For more information, see "Defining filters".

Optionally, the FilterConfig object is destroyed in the filter's destroy method, as the following code shows:

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

Understanding the FilterChain object

JRun passes the FilterChain object into the filter's doFilter method. Each filter passes control to the next filter or to the target resource, but eventually regains control when the downstream filters finish processing and pass control back up the chain. You can think of using multiple filters in a chain as winding and unwinding a stack.

As each filter finishes processing the request, it returns control to the chain. From there, processing can occur in the next filter (if there is one), the previous filter, or at the target resource.

Filters can include logic to determine when or whether to return control to the chain. If the last filter calls the chain and there are no more filters in the chain, then the request is passed to the target resource.

If a filter's logic prevents it from returning control to the chain, the chain is broken and the response is sent back through the filter chain and to the client. The remaining downstream filters (if any) in the chain are ignored.

Filters that break the chain can forward the request to another resource; thus some filters may never see the request. A filter can break the chain using a RequestDispatcher and forward or include. The dispatched request is not subject to any further filters in the chain despite any container mappings, and is returned to the client.

The following figure shows this process:

A client request goes to a JRun server, which passes the request to the first filter, second filter, and then the target resource. Then the request passes back to the second filter, to the first filter, to JRun, and finally back to the client.

The FilterChain object has one method:

doFilter(ServletRequest request, ServletResponse response)

Using the doFilter method, you pass the request and response to the next filter in the chain. If the current filter is the last or only filter in the chain, the request and response are passed to the target resource. When the target resource finishes processing, the request and response are passed back to the chaining filter, which then passes them to the previous filter in the chain (if any), and so on. When the first or only filter in the chain is reached, the response is passed back to the client.

Filters must call the chain's doFilter method in the filter's doFilter method in order for the target resource to be accessed and the response to be returned, as the following code shows:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
  throws java.io.IOException, javax.servlet.ServletException {
�chain.doFilter(request,response);

}

Creating a generic filter class

All filters implement the javax.servlet.Filter interface, so you must override that interface's methods in each filter. Because most filters do not perform any unique actions in the init and destroy methods, a generic class that overrides these methods can help prevent unnecessary coding.

To take advantage of the object-oriented nature of Java, create a generic class that implements the Filter interface and overrides all the methods. Then extend the new generic class with your filters and provide customized logic for only the methods you want. In most cases, you only override the doFilter method.

The following code shows the GenericFilter class that implements the javax.servlet.Filter interface. Your filters can then extend this class and override only the necessary methods.

package jrunsamples.filters;
import javax.servlet.*;
public class GenericFilter implements Filter {
�public FilterConfig filterConfig;
�public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain) 
  throws java.io.IOException, javax.servlet.ServletException {
��chain.doFilter(request, response);
�}
�public void destroy() {
��this.filterConfig = null;
�}
�public void init(FilterConfig filterConfig) {
��this.filterConfig = filterConfig;
�}
}

By extending the GenericFilter as follows, you can implement the simple filter example (see "Simple filter example"):

package jrunsamples.filters;
import javax.servlet.*;
public class SimpleFilter extends GenericFilter {
�public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
  throws java.io.IOException, javax.servlet.ServletException {
��// filter logic
��chain.doFilter(request,response);
��// filter logic
�}
}

 

Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/jrun/4/Programmers_Guide/filters3.htm