WildcardsForActionMappings

One of the new features in Struts 1.2. is the support of wildcards for action mapping. A sample could be found at http://struts.apache.org/struts-action/userGuide/building_controller.html#action_mapping_example This feature can be used in advance to generalize the actions even more. Consider below as a very usual example: Imagine a system which has an accounting form that enables user to inserts, updates and search for its accounts. This system also has a product form which does the same for product. A good deign is to do encapsulate all related forms actions (search, edit, form initialization etc...) in one FormAction. If we put all action in one java action, then will we found which action must take place for each request to the form? Is this request for editing account or searching it? Well, we can use the old fashion(!) DispatchLookUpAction and deal with dispatch parameter. Another alternative is using action wild cards consider below sample:

Example

        <action path="/**/*Form" <!-- we path to parameter here-->
                type="com.mycompany.{1}FormAction"
                name="{1}{2}FormBean"
                parameter="dispatch"
                validate="false"
                scope="request"
                >
            <forward name="show.Search.form"
                      path="/main/form/{1}{2}Form.jsp"/>
            <forward name="show.Edit.form"
                      path="/main/form/{1}{2}Form.jsp"/>
            <forward name="success.Search"
                     path="/main/form/{1}{2}Form.jsp"/>
            <forward name="success.Edit"
                     path="/main/form/{1}{2}Form.jsp"/>
Too bad struts does not support wild card for forward names!!!

The above pattern accepts /Account/EditForm.do, /Account/SearchForm.do, /Product/SearchForm.do etc... So no need for sending dispatch parameter, the url itself contains the requested action (Edit,Search). In your action, you can get this second parameter by parsing the request URI. (Maybe strust has a utility for it!) Below code does this by calling the getMethod,

    String getActionPath(HttpServletRequest req) {
        String path;
        path = req.getRequestURI();
        path = path.substring(path.lastIndexOf('/') + 1);
        return path;
    }

    String getMethod() throws WebException {
        String method = getActionPath(Req);
        //Assume that the path is /Account/SearchForm.do etc...
        method = method.replaceAll("Form.do", "");
        log.debug("Method '" + method + "' found from action path.");
        if (!method.equals(EDIT_FORM_METHOD) && !method.equals(SEARCH_FORM_METHOD)) {
            throw new WebException("Invaild internal Method", WebException.INVALID_INPUT);
        }
        return method;
    }

So: user calls /Account/EditForm.do Struts calls AccountFormAction class. And in this action you can get the actual method. Struts also forwards to proper jsp, which for this sample it will be /main/form/AccountEditForm.jsp

Imagine the lot that you can do when mixing above feature with a nice parent class, which does all same tasks for actions by itself, and only calls use casespecific methods. As you might have notice all forms have the same flow and same task should be done for all of them, form should be displayed, after user submitted back the form, form must be validated first for user input ( not null fields etc) then for business validation. If user did not entered valid data, form is initialized and send back to user....

So you can create a parent for all form actions, like below:

public abstract class BaseFormAction
{
   execute()
  {
    //YOU CAN DO LOT HERE!!!!

     //get the method();
     //Validate user inputs. If there is an error forward to show.METHOD.from
     //This METHOD will be Edit or Search 

     //if method is search
     // call Search();
    // if method is add
    // call Add()
   }
abstract Search()
abstract initSearch()
abstract Edit()
abstract initEdit()
}

All abstracts will be implemented in actual classes ( AccountFormAction ).

WildcardsForActionMappings (last edited 2009-09-20 23:12:15 by localhost)