DispatchAction


DispatchAction is another useful built-in Struts Action. However you cannot use it as is. You will have to extend it to provide your own implementation. An example will make things clear. Consider an online credit card application. Customers fill the credit card application online. The bank personnel get a List screen as shown in Figure 4.1 and they can act in one of four ways - Approve, Reject or Add Comment. Consequently there are three images each being a < html:link >.


Figure 4.1: Screen Credit Applications page as seen by the bank staff.

One way of dealing with this situation is to create three different Actions ‚ ApproveAction , RejectAction and AddCommentAction . This is a valid approach, although not elegant since there might be duplication of code across the Actions since they are related . DispatchAction is the answer to this problem. With DispatchAction , you can combine all three Actions into one.

The DispatchAction provides the implementation for the execute() method, but still is declared as abstract class. You start by sub-classing DispatchAction . Let us assume that CreditAppAction , a sub-class of DispatchAction is used to implement the above-mentioned presentation logic. It has four methods ‚ reject() , approve() and addComment() . The CreditAppAction class definition is shown in Listing 4.1.

Listing 4.1: Example DispatchAction
 public class CreditAppAction extends DispatchAction {    public ActionForward reject(ActionMapping mapping,                 ActionForm form, HttpServletRequest request,                HttpServletResponse response) throws Exception    {        String id = request.getParameter("id");        // Logic to reject the application with the above id        ... ... ...        mapping.findForward("reject-success");    }    public ActionForward approve(ActionMapping mapping,                 ActionForm form, HttpServletRequest request,                HttpServletResponse response) throws Exception    {        String id = request.getParameter("id");        // Logic to approve the application with the above id        ... ... ...        mapping.findForward("approve-success");    }    public ActionForward addComment(ActionMapping mapping,                ActionForm form, HttpServletRequest request,                HttpServletResponse response) throws Exception    {        String id = request.getParameter("id");        // Logic to view application details for the above id        ... ... ...        mapping.findForward("viewDetails");    }        ...   ... } 
 

You might be wondering why all the three methods take the same four arguments ‚ ActionMapping , ActionForm , HttpServletRequest , HttpServletResponse . Don ‚ t worry, you will find the answer soon.

For a moment, look at the four URLs submitted when the bank staff perform the three actions as mentioned before. They would look something like this.

  • http://localhost:8080/bank/screen-credit-app.do? step=reject &id=2

  • http://localhost:8080/ bank/screen-credit-app.do? step=approve &id=2

  • http://localhost:8080/bank/screen-credit-app.do? step=addComment &id=2

An interesting thing to notice is that the value of the HTTP request parameter named step is same as the four method names in CreditAppAction . This is no coincidence . DispatchAction (the parent class of CreditAppAction ) uses the value of the HTTP request parameter step to determine which method in CreditAppAction has to be invoked. In the execute() method, DispatchAction uses reflection to invoke the appropriate method in CreditAppAction . For this reason, the arguments on all the three methods in CreditAppAction are fixed and have to be ‚ ActionMapping , ActionForm , HttpServletRequest , and HttpServletResponse in that order. Otherwise the method invocation by Reflection fails.

Okay, so part of the puzzle is solved . But how does DispatchAction know to look for the HTTP request parameter specifically named step in the URL? The simple answer is that it doesn ‚ t. You will have to tell it explicitly. And this is done in the ActionMapping for /screen-credit-app.do . The ActionMapping for the URL path ‚“ /screen-credit-app.do ‚½ is declared in struts-config.xml as shown in Listing 4.2.

Listing 4.2: ActionMapping for the DispatchAction
 <action path="/screen-credit-app"   input="/ListCreditApplications.jsp"  type="mybank.example.list.CreditAppAction"   parameter="step"  scope="request"   validate="false">       <forward name="reject-success"                 path="RejectAppSuccess.jsp"                 redirect="true"/>   ..  </action> 
 

The section highlighted in bold is what makes this Action different from the rest. The type is declared as mybank.example.list.CreditAppAction ‚ you already knew that. Now, let us look at the second attribute in bold. This attribute, named parameter has the value ‚“ step ‚½. Notice that one of the HTTP request parameter in the four URLs is also named ‚“ step ‚½. Now, it is all coming together. DispatchAction knows what parameter to look for in the incoming URL request through this attribute named parameter in struts-config.xml . From the value of parameter attribute, it knows the method to be invoked on the subclass. Since the arguments and their order in these methods is fixed by DispatchAction , the method invocation by reflection at runtime is successful. If for any reason, the arguments on these methods are different; the method invocation fails at runtime.

DispatchAction can be confusing in the beginning. But don ‚ t worry. Follow these steps to setup the DispatchAction and familiarize yourself with the steps.

  1. Create a subclass of DispatchAction .

  2. Identify the related actions and create a method for each of the logical actions. Verify that the methods have the fixed method signature shown earlier.

  3. Identify the request parameter that will uniquely identify all actions.

  4. Define an ActionMapping for this subclass of DispatchAction and assign the previously identified request parameter as the value of the parameter attribute.

  5. Set your JSP so that the previously identified request parameter (Step 3) takes on DispatchAction subclass method names as its values.

    Design Tip: Use DispatchAction when a set of actions is closely related and separating them into multiple Actions would result in duplication of code or usage of external helper classes to refactor the duplicated code. In the above example DispatchAction was used handle hyperlinks . DispatchAction is a good choice when there are form submissions using the regular buttons (not the image buttons). Just name all the buttons same. For instance,

     <html:submit property="step">Update</html:submit>              <html:submit property="step">Delete</html:submit> 

    and so on. Image buttons is a different ball game. Image button usage for form submission and DispatchAction are exclusive. You have to choose one. See Chapter 6 on Struts tags for details on Image buttons.

In the above example we used the DispatchAction and used methods that has ActionForm as one of its arguments. As you learnt in the last chapter, an ActionForm always existed in conjunction with the Action. Earlier in this chapter, we dealt with ForwardAction and we neither developed our Action or ActionForm. In that context we stated that having an ActionForm was optional. That holds true even if the Action is a custom coded one like the CreditAppAction . If the ActionMapping does not specify a form bean, then the ActionForm argument has a null value. In the Listing 4.1, all the four methods got a null ActionForm. But that did not matter since the HTTP request parameters were used directly in the Action. You can have a Form bean if there are a lot of HTTP parameters (and perhaps also require validation). The HTTP parameters can then be accessed through the Form bean.




Struts Survival Guide. Basics to Best Practices
Struts Survival Guide: Basics to Best Practices (J2ee Survival Series)
ISBN: 0974848808
EAN: 2147483647
Year: 2004
Pages: 96

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net