Chapter 21 Using Filters and Event Listeners


Servlet filters

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 that they are declared in the deployment descriptor, then it adds 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 Jaguar Manager to add a new filter to a Web application and map it to either a servlet name or a URL pattern.

Steps Adding a new filter to a Web application

  1. Expand the Web Applications folder, then highlight the icon that represents your application.
  2. Choose File | New Web Component.
  3. Select Filter and enter a name for the filter.
  4. Click Add. This displays the Filter Component Properties dialog box.
  5. On the General tab, enter:
  6. On the Init-Params tab, enter the initialization parameters as name/value pairs. When the filter is initialized, it receives a FilterConfig object that contains these parameters.
    1. Click Add to display the New Property dialog box.
    2. Enter a property name and property value, and click OK.



    To edit an initialization parameter, highlight the property and click Modify. Edit the property name or value, and click OK.

    To delete an initialization parameter, highlight the property and click Delete.
  7. Click OK.

"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.

Note   The setFilterConfig method is no longer supported (as of version 4.1); it has been replaced by init and destroy.

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 mthod, 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
   }
 
}

Note   If you want to use page caching for servlets whose responses are modified by a filter, see "Using page caching with filters that modify a response " .

Custom headers

To add custom response headers for static resources, EAServer provides the filter class com.sybase.jaguar.servlet.AddHeadersFilter. The filter is designed to add cache-related and simple name/string header information to a response. The initialization parameters that you pass to the filter must be in this format:

(name=header_name, value=type:value_type&val:value)
where header_name is the title of the header, and value_type and value can be:

Value type Description Sample value
String A text string. "Add this to the header."
Date GMT date specified as,
[+|-] ddDhhHmmMssS.
To indicate the current date, set value to +0 .
To indicate the current date plus 20 days, 10 hours, 30 minutes, and 20 seconds, set value to +20D10H30M20S .
Etag EAServer generates an entity tag (etag) based on the file's length, last modified time, and the sum of the file. value can be either "E" or "WE". "WE" specifies a weak etag. If you set value to "E", EAServer writes something like this in the header: b222308-205-e28daea590 .

This example creates an instance of AddHeadersFilter and passes the header name, value type, and value:

com.sybase.jaguar.servlet.filter.init-param=
(name=Expires, value=type:date&val:+365D),
(name=Cache-Control, type:string&val:max-age=3600)
which adds these two lines to the response:
Expires: Wed, 15 May 2002 15:31:22 GMT
Cache-Control: max-age=3600

For more information

For more information on filters and programming customized responses, see the Java Web page .

 


Copyright © 2002 Sybase, Inc. All rights reserved.