http://www.developer.com/

Back to article

Implementing the Intercepting Filter Pattern in Your Enterprise Java Applications


July 13, 2006

Since the publication of the renowned book Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson, and Vlissides, also known as the Gang of Four (GoF) book in 1995, the wave of design patterns in an enterprise world has gained enough momentum to reach the mainstream developers and IT managers. Something thatonce was only invented to be used and shared by uber-developers to simplify reusability and maintenance of their projects was now accepted as a de facto way to do software engineering. The "epidemic" of design patterns has reached its tipping point and spread like wildfire. The book served as a catalyst for the most famous and original patterns, which were at that time mostly in C++. The patterns focused on the object-oriented aspects of software development. They were categorized into three main categories: creational, structural, and behavioral.

Java Patterns

As the Java language matured and gained popularity, most* of the original patterns were ported to it. In fact, when the language was created, many of the design patterns were built right into it from the start. For example, listeners in Java Swing are the classic Observer pattern. Java's intrinsically object-oriented nature facilitated in identification and creation of many new patterns. These new patterns could also be categorized as belonging to a creational, structural, or behavioral group. Recently, another category of "enterprise" or n-tier patterns has emerged.

* Some patters in C++ deal with pointer structures and Java language elegantly avoids this feature.

When Java made a shift from the client to the server and became the language of choice for enterprise Web development, developers working on the server side realized the need for design patterns dealing with information flow, communication between application tiers, database persistence, resource locating, and so forth. In other words, all of the enterprise services could benefit from the design patterns that would enforce reusability and maintainability on the application level, rather then on the object level.

In this article, I will discuss the enterprise Intercepting Filter pattern. The Intercepting Filter pattern can be classified as a presentation tier pattern because it deals with requests from the presentation tier. This pattern is Web-application specific, and generally cannot be applied in other types of applications, but its concepts are generic and it is related to the structural Decorator (Wrapper) pattern, which I will discuss in this article as well. The Servlet specification 2.3, which is now finalized, incorporates this pattern, and I will focus on the differences between the Servlet and custom implementation methods. I also will describe the reasoning behind this pattern and how can it be reused throughout Web applications.

Intercepting Filter Concepts

In the world of Web development, applications are structured around requests and responses. The client sends a protocol request for some action and the server, after carrying out that action, responds with the reply to the client. Because all Java Web applications deal with this logic, if additional actions are required to be done on the server before it can send the reply, they must be aggregated into the same code that does the main response. For example, a client wants to upload a file to the server. On the server side, the application should authenticate the user before accepting anything, scan the file for viruses, and store the file in the database and finally send a success or failure response back to the client. In a different application, a file can be stored in a file system, but the authentication and scanning components can be repeated.

The Intercepting Filter, as the name implies, intercepts the requests and helps separate all the tasks that need to be done on the server into reusable components. The actions/filters can be assigned to specific requests, chained in any order, and added or removed within the application configuration. After the filters complete, they pass the request to the intended recipient, in this case Servlet or JSP. After the server is finished, a response is sent to the client (see the following diagram).

As you can see, this design pattern is dealing on the application level with the actions and the flow. It does not deal with objects like Singleton or Factory patterns, for instance. The filters can do any task imaginable from outputting logging about the request to modifying the request itself.

Custom Implementation

The custom solution of this problem can have many different implementations. I will present one of them, but in general any custom method can be a variation of the Decorator pattern (also known as a Wrapper pattern) modified and applied to the n-tier structure. I should note that any custom solution is not as transparent as the Servlet API implementation because it cannot transparently wrap the request and the response objects.

You'll look at the Decorator pattern first before looking at the Intercepting Filter. The Decorator pattern attaches additional responsibilities to any object dynamically, hence the name "decorator." Here is a simplified example of a decorator pattern. (See the code section for the complete source for this pattern and another example.)

Given any object that does some action:

public class OriginalObj {
   private java.lang.String text = "";
   public OriginalObj() {}

   public OriginalObj(String text) {
      this.text = text;
   }

   public void doStuff() {
      System.out.println(text);
   }
}

It can be extended via a Decorator object that wraps the original object and adds extra responsibilities or actions. This example subclasses and wraps at the same time; in a true implementation, a generic interface should be used.

public class Decorator extends OriginalObj {
   public OriginalObj obj;
   public Decorator(OriginalObj obj) {
      this.obj = obj;
   }

   public void doStuff() {
      obj.doStuff();

      // other data operations can be added here...
   }
}

The invocation can be the following:

public static void main(java.lang.String[] args) {
   // normal use
   OriginalObj obj = new OriginalObj("vlad");
   obj.doStuff();

   Decorator objDecor2 = new Decorator(obj);
   objDecor2.doStuff();

   }

When this pattern is applied to the Web application to intercept requests, it can be changed to do actions on the request object before the Servlet is handled that request. J2EE API conveniently provides a javax.servlet.http.HttpServletRequestWrapper class, which by itself implements the Wrapper or Decorator pattern and is a implementation of the HttpServletRequest interface. Therefore, to implement a custom Intercepting Filter, a request is first passed to some custom object that extends from HttpServletRequestWrapper, which does some operation and then is passed to the intended target object. The custom classes can implement a single interface and be chained together.

For example:

import javax.servlet.http.HttpServletRequest;

public interface CustomFilterInterface {
   void execute(HttpServletRequest request);
}


import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;

public class CustomIFilter extends HttpServletRequestWrapper
   implements CustomFilterInterface {
   public CustomIFilter(HttpServletRequest request) {
      super(request);
      this.execute(request);
   }

   public void execute(HttpServletRequest request) {
      //do something with the request here...
   }

}

Here is an example of Filter Chain that can be set up with any number of Intercepting Filters and invoked from a Servlet or JSP.

public class FilterChain {

   private ArrayList myFilters = new ArrayList();

   public FilterChain(CustomFilterInterface filter) {
      addFilter(filter);
   }

   public void processFilter(HttpServletRequest request) throws
      ServletException, java.io.IOException {
      CustomFilterInterface filter;

      Iterator filters = myFilters.iterator();
      while (filters.hasNext()) {
         filter = (CustomFilterInterface) filters.next();
         filter.execute(request);
      }
   }
   public void addFilter(CustomFilterInterface filter) {
      myFilters.add(filter);
   }

}

The flow of the request to the Servlet or JSP will be as following:

Unless a more robust implementation is created, this custom implementation will require you to set up all intercepting filter chains programmatically. Dynamically using filters per request will require more logic and Reflection API, or a property file to set up which filter or set of filters should be invoked per Servlet or JSP. However, even that will not make this implementation completely transparent because some calls will still need to be placed in the target Servlet or JSP.

Servlet Implementation

Because this pattern is very useful, the creators of the Servlet API felt they need to provide its implementation. Therefore, the Servlet specification 2.3 included a filter and filter chain API. It also takes care of filter configuration via a main web.xml file. Moreover, intercepting filters can be set up transparently from the target Servlet or JSP and can wrap the request object. This implementation eliminates the need to write a lot of custom code, but on the other hand, it has limitations due to its predefined interfaces, and a requirement for a developer to learn its APIs.

Here is a part of the web.xml file that shows two filters that will intercept all requests to any URL pattern. However, the URL pattern can be set to be as specific as one Servlet only.

<servlet>
   <servlet-name>mainservlet</servlet-name>
   <servlet-class>intercepting_filter.MainServlet</servlet-class>
</servlet>

<servlet-mapping>
   <servlet-name>mainservlet</servlet-name>
   <url-pattern>/mainservlet</url-pattern>
</servlet-mapping>

<filter>
   <filter-name>servletfilter</filter-name>
   <filter-class>intercepting_filter.ServletFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>servletfilter</filter-name>
   <url-pattern>/*</url-pattern>
   <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter>
   <filter-name>scanfilter</filter-name>
   <filter-class>intercepting_filter.ScanFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>scanfilter</filter-name>
   <url-pattern>/*</url-pattern>
   <dispatcher>FORWARD</dispatcher>
</filter-mapping>

This configuration tells the container to invoke the filter first on any request before handling the request object to the main Servlet. For example, ScanFilter can check whether the request type is "multipart form data" (a special type for file upload) and scan all attached files before the request is passed forward. This filter can be reused in different applications because it is not tied with any specific application code.

Here is a sample of ScanFilter that uses the O'Reilly package to work with multipart requests.

import com.oreilly.servlet.multipart.*;

public class ScanFilter extends HttpServlet implements Filter { private FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } //Process the request/response pair public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) { try { String contentType = request.getContentType(); // Only filter this request if it is multipart encoding if (contentType.startsWith("multipart/form-data")) { MultipartParser mp = new MultipartParser(request, 10*1024*1024); Part part; while ((part = mp.readNextPart()) != null) { String name = part.getName(); if (part.isFile()) { // it's a file part FilePart filePart = (FilePart) part; if (filePart != null) { // scan it for viruses } } } } // end if filterChain.doFilter(request, response); } catch (ServletException sx) { filterConfig.getServletContext().log(sx.getMessage()); } catch (IOException iox) { filterConfig.getServletContext().log(iox.getMessage()); } }

Conclusion

In this article, I focused on the Intercepting Filter design pattern. It is one of the externally useful patterns in the category of enterprise Web development and should not be overlooked. It can simplify Web application development, maintenance, and reusability, as well as promote logic separation. As Web development technologies evolve, this pattern will probably change as well, but the main concepts should remain. Whether you will use a Servlet API or a custom solution to implement Intercepting Filter, you will benefit from its concepts in the long run.

Download Source

References

About the Author

Vlad Kofman is a Senior System Architect. He has implemented enterprise-scale projects for the major Wall Street firms, defense contracts, and the U.S. government. His main interests are object-oriented programming methodologies and design patterns.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date