StrutsCatalog: Use a base Action for your application

Often, the Actions in your application are able to share a common set of utility methods. To make it easy to share utilities methods, declare a base Action for your application and extend all of your custom Actions from this base. Here's one example of a base Action with several utility methods:

http://cvs.apache.org/viewcvs/jakarta-struts/contrib/scaffold/src/java/org/apache/struts/scaffold/BaseAction.java

Note that to be thread-safe, utility methods must pass all parameters through the method signature. Actions must not share parmeters through member fields.

If key tasks needs to be completed in each Action's

 execute 

method, one strategy is to create a new abstract methods for your subclasses to use in lieu of

 execute 

. The base Action class does its business, and if all is well, then returns the result of the new method. This allows you to change the signature of your new method, if there is ever any reason for that, and provides a cleaner flow.

    public ActionForward execute(ActionMapping mapping, 
                 ActionForm form, 
                 HttpServletRequest request, 
                 HttpServletResponse response) 
    throws Exception { 

        // Application specific behaviour 
        // if everything is kosher call subclass extension point 

        return ( executeAction(mapping,form,request,response, myParameter ) ) 
   } 

where

 executeAction 

is an abstract method of the base class. We've added an extra parameter here for demonstration purposes. If your application doesn't need to change the signature, then simply retain the Struts execute signature in your own implementation.

TedHusted


Comments:

This is a great pattern, particularly if you know that there are certain errors/exceptions that will require common handling. In my company, applications may be available near 24/7 but sections of the database get locked by batch update processes etc. at irregular intervals. As such, I have a base action that checks SQL errors and sends to a global forward dbUpdate when an update is in progress.

--David Hibbs

Comments:

I have been using this idea on mid-size project and finally changed my mind. It's fine but sooner or later you 'll realize that it would be cool to use built-in struts actions like DispatchAction and others that provide useful functionalities. Then, as java does still not provide multiple inheritance, you are forced to either build a full hierarchy of abstract actions (with one abstract actions for each kinda of built-in action you want to reuse), or you end up adding more and more functionality to your base class. It seems to me that the only real interest of this method is when you want to enforce the execution of a given piece of code on each action execution (like verifying that the user is logged in), but infact to do this a proper customization of the ActionServlet or RequestProcessor should be better (or even a Servlet filter but this a more tedious job).

– Nicolas JOUVE from France

@Nicolas issue:
I didn't try this, but it could be handled using a Decorator pattern. Although stacking Actions doesn't sound so well in the first place.

– Axel GROSS

For those needing DispatchAction capabilities while using your own base Action, the solution is the new ActionDispatcher class that was introduced in Struts 1.2.7. It provides DispatchAction functionality without having to inherit from a particular class, and can be extended to provide custom Dispatch behavior.

– Hubert Rabago

For those wanting more than DispatchAction can provide, the solution is EventActionDispatcher class (Struts 1.2.9, Struts Extras 1.3.1+) It provides all DispatchAction functionality and more:

  • One action mapping can contain several event definitions.
  • Submit buttons can have any caption; caption can be changed in runtime.
  • No event-to-method map is needed.
  • Action method name can be either used directly on a web page, or can be aliased with an event name.
  • It is possible to define a default method if event is not recognized.
  • If event is not recognized and default method is not defined, the dispatcher invokes unspecified method.
  • Standard Cancel buttons is hooked up to cancelled method and does not have to be defined explicitly.

– Michael Jouravlev

  • No labels