Friday 18 January 2008

Struts 1.3 Tutorial.

The key difference between the struts 1.2 and 1.3 is the RequestProcessor. In 1.2 we had the request processor where a series of method were executed in an order. Since 1.3 we have the chain of commands pattern based request processor, where each request-processing step is composed into a pluggable command. You can inject new command and remove commands from the pattern and it gives you more flexibility and control on request processing.

If you know 1.2 and want to switch to 1.3 this matters for you otherwise skip this Para. We know the different methods we had in the 1.2 request processor and the following list gives you what has been changed to what.

  • 1.2 -> 1.3
  • processPath -> SelectAction
  • processException -> ExceptionCatcher / ExceptionHandler
  • processMapping -> SelectAction
  • processRoles -> AuthorizeAction
  • processActionForm -> CreateActionForm
  • processPopulate -> PopulateActionForm
  • processValidate -> ValidateActionForm / SelectInput
  • processActionCreate -> CreateAction
  • processActionPerform -> ExecuteAction
  • processPreprocess -> LookupCommand with optional="true". Multiple occurrences of this can easily be added, to support additional processing hooks at any point in the chain without modifying the standard definition.
Let us demonstrate the request processors in 1.2 and 1.3 through the pictures and the difference is self-explanatory.


Struts 1.2

Struts 1.3




Coming back to our discussion on composable request processor. Obvious questions are. Where these commands are defined? How the order is determined? What if I want to add/remove something? To get all these answers we need to understand the Chain of responsibility pattern first. Let us do this step by step and try to keep it simple and short.

The Chain package defines five key interfaces:

Context. A Context represents the state of an application. In the Chain package, Context is a marker interface for a Map.The Context containing the attributes/values needed to complete a transaction[set of units of work together in a given order].

Command. A Command represents a single unit of work. A Command has a single method: public boolean execute(Context context)
Context contains values in a Map, which we use to do a unit of work logic. We can assemble multiple Commands into a Chain to make a complex unit of work. How this chain of commands executes? The next Command in the chain is executed only if the current one returns false and the chain terminates if Command returns true.

Chain. Chain implements the Command interface, so a Chain can be used interchangeably with a Command. An application doesn't need to know if it's calling a Chain or a Command. A Chain can nest other Chains as desired.

Filter. A Command that implements Filter can safely release any resources it allocated through the postProcess method, even if those resources are shared with other Commands. Every time we want to do a post execute actions we implement the filters to the Command.

Catalog. A Catalog is a collection of logically named Commands (or Chains) that a client can execute. This is where we assemble all the commands together, we associate order of executions etc.