Servlet Command Pattern

Intent

Encapsulate an HTTP request as an object, thereby letting you parameterize responses to different requests, queue or log requests, and support undoable operations.

Discussion

This adaptation of the CommandPattern is one way to handle many different requests in a centralized object (the command or dispatcher servlet) and invoke different responses depending on the particulars of a given request. It is often the case that a dynamic web site will allow a visitor to work through a series of different actions, such as subscribing, ordering, modifying preferences, and all the actions operate on the same core objects in the application. The command servlet and dispatch different responses based on form submit paramters. It is also possible to paramaterize the responses based on such criteria as the browser vendor/version, device type (WAP gateway or PDA), or any of the other HTTP header info that might be available in an HTTP request.

Example

A simple form will have a hidden field named "action", which is set by the server to one of several values depending on the form the site visitor is filling out. For example "createUser", "modifyPreferences", "checkoutCart". In the dispatching servlet, the value for the request parameter action is used to determine which business logic to execute. Often, but not always, this is a class that is dynamically determined, using the ParameterClasses idiom.

-- StevenNewton

I have found it better to have the hidden field named "form" or "page", and containing the name of the form/page, and let the receiving servlet decide the intended "action" from the fields filled in, and the submit-button pressed. --ChristofferHammarstrom


We are using a pattern similar to this on the current project I am working on. We use the ParameterClasses idiom. Each form (or any hyperlink for that matter) calls our controller (or dispatcher) with a "command" variable. The variable is the name of the class to load to execute the command. Each command class has one method:

 void execute(Hashtable arguments);

As each request comes in, the controller take the form elements (with a call to getParameter) and puts them in a Hashtable. It also includes in this Hashtable any objects passed in with the request (with a call to getAttribute). The controller then performs a Class.forName() on the command parameter. It takes the resulting class and calls the execute method, passing in the Hashtable it previously constructed. The Session can also be placed in this Hashtable. The receiving command parses the Hashtable, extracting and modifying any entries it needs to. It then places a "page.next" entry in the Hashtable before returning.

Once the command returns, the Hashtable is re-parsed and parameters and attributes are re-attached to the request. The controller then forwards control to the "page.next" attribute.

This allows us a great deal of flexibility:

-- IainLowe


An interesting variation on this involves modelling the flow through a complicated application as a directed graph or state machine indicating the permissible paths from one page to another. If you record this as data then it becomes possible to dynamically alter the flow of control by merely altering the EdgeMatrix? of your website.


IainLowe may be describing a pattern similar to one I have. A hidden magic number on the page that generates the request can be used to map the request object to a specific page object in the servlet. That page object can then process the request and determine, dynamically, the next page to vend (in the response). This next page also gets a new magic number.

This gives the same sort of flexibility as modifying the EdgeMatrix?, but without the need for a centrallized graph or network to edit. It also greatly simplifies the construction of servlet frameworks -- abstract classes can provide the necessary interaction with requestor, while descendents can specialize the specific navigational decisions.

Meanwhile, this approach provides a solid and reliable model of the session, without requiring browser participation. In fact, multiple sessions can proceed in parallel from the same browser -- a real advantage in situations where one system and browser is shared among multiple users (such as a shop-floor information system in a factory).

-- TomStambaugh


EditText of this page (last edited June 21, 2004) or FindPage with title or text search