October 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Implementing the Intercepting Filter Pattern in Your Enterprise Java Applications

  • July 13, 2006
  • By Vlad Kofman
  • Send Email »
  • More Articles »

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.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel