Featured Whitepapers
Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Untangle your servlet code with reflection

Simplify servlet structure by breaking down functionality into separate methods

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Despite the elegance of the Servlet API, real-world servlet classes tend to have pages of code in their doGet() and doPost() methods, often with complex conditional logic. Over time, more code must be added in response to evolving business needs. Long methods with complex branching result in a major headache for the unlucky developer who must maintain that code. Good programming style suggests that such branching should be avoided.

This article presents a technique to modularize the functionality of a complex servlet using reflection, thereby simplifying the servlet structure. Specifically, the CTLServlet base class parses the request URL to determine the name of an appropriate handler, finds a method by that name in the implementation class, and then invokes the method to handle the request. That makes it easy to break down servlet functionality into separate methods, and thus avoid very long method bodies within doGet() and doPost().

As I will describe in more detail, this technique has several other important advantages. It replaces long conditional dispatching code with a simple lookup. It encourages a disciplined relationship between URLs and handler methods, which makes it easier to analyze and extend servlet behavior. It is very lightweight, and thus imposes little burden upon developers. And it readily supports a number of interesting extensions, such as trace functionality for debugging, and a more object-oriented style.

About reflection

The Reflection API provides a way to discover what an object can do at runtime and to execute the discovered capabilities. As Michael T. Portwood, a presenter at JavaOne, put it, reflection can make applications more "simple, flexible, and pluggable" without sacrificing performance or increasing overall program complexity. The approach used in this article parallels a technique described in that JavaOne presentation (see Resources). This technique uses reflection to implement a generic ActionListener in Swing or AWT code (see Resources). The reflection-based code is much shorter and simpler than its conditional alternative.

For example, the conventional conditional approach compares the ActionEvent's command to a set of known strings and then branches to an appropriate handler method, like this:

public void actionPerformed(ActionEvent ev) {
   String command = ev.getActionCommand();
   if (command.equals("start") {
      start();
   }
   else if (command.equals("stop")) {
      stop();
   }
   else if (command.equals("another")) {
     another();
   }
}


Notice that you dispatch to a method that matches the name of the action command in the ActionEvent object. Reflection can capture this dispatching pattern, as follows:

public void actionPerformed(ActionEvent ev) {
  try {
         Method m = getClass().getMethod(getActionCommand(), new Class[0]);
         m.invoke(this,new Object[0]);
  }
  catch (Exception ex) {
  
  }
}


Now you can easily add new command handlers, simply by adding new zero-argument methods to your class -- without ever updating the dispatching code.

The extension of this idea to servlets is pretty straightforward, although surprisingly powerful. Instead of finding the name of a command in an ActionEvent object, you find the name in a component of the request URL. Instead of calling a zero-argument method with that name, you call a method that takes two arguments, one of type HttpServletRequest and the other of HttpServletResponse. With that approach, you can break up the pages of code in your doGet() and doPost() methods into many smaller well-named methods; eliminate complex dispatching code; and make it much easier to add new functionality to an existing servlet.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources