Recipe7.6.Creating a Wizard-Style Page Flow


Recipe 7.6. Creating a Wizard-Style Page Flow

Problem

You want users to have a wizard-style page flow experience.

Solution

Implement a subclass of LookupDispatchAction that supports operations for the navigational functionsprevious, next, and finishand template methods for the business logic. For each discrete step of the workflow, extend this subclass, placing the business logic for each step in the provided template methods. (See Example 7-4.)

Example 7-4. LookupDispatchAction for wizards
package com.oreilly.strutsckbk.ch07; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.actions.LookupDispatchAction; public class WizardLookupDispatchAction extends LookupDispatchAction {         public WizardLookupDispatchAction( ) {         keyMethodMap = new HashMap( );         keyMethodMap.put("button.previous", "doPrevious");         keyMethodMap.put("button.next", "doNext");         keyMethodMap.put("button.finish", "doFinish");     }          public ActionForward doPrevious( ActionMapping mapping,              ActionForm form,             HttpServletRequest request,              HttpServletResponse response) throws Exception {         processPrevious(mapping, form, request, response);         return mapping.findForward("previous");     }             protected void processPrevious( ActionMapping mapping,              ActionForm form,             HttpServletRequest request,              HttpServletResponse response) throws Exception {     }                 public ActionForward doNext( ActionMapping mapping,              ActionForm form,             HttpServletRequest request,              HttpServletResponse response) throws Exception {        processNext(mapping, form, request, response);        return mapping.findForward("next");     }            protected void processNext( ActionMapping mapping,              ActionForm form,             HttpServletRequest request,              HttpServletResponse response) throws Exception {     }            public ActionForward doFinish( ActionMapping mapping,             ActionForm form,            HttpServletRequest request,             HttpServletResponse response) throws Exception {       processFinish(mapping, form, request, response);       return mapping.findForward("finish");     }             protected void processFinish( ActionMapping mapping,              ActionForm form,             HttpServletRequest request,              HttpServletResponse response) throws Exception {     }     protected Map getKeyMethodMap( ) {         return keyMethodMap;     }         }

Specify the workflow for the wizard in the struts-config.xml file:

<!-- Wizard mappings --> <!-- Step 1 --> <action    path="/ViewStep1"            name="WizardForm"           scope="session"            type="org.apache.struts.actions.ForwardAction"       parameter="/step1.jsp"/> <action    path="/ProcessStep1"            name="WizardForm"           scope="session"            type="com.oreilly.strutsckbk.ch07.WizardLookupDispatchAction"       parameter="methodToCall">     <forward name="next" path="/ViewStep2.do"/> </action> <!-- Step 2 --> <action    path="/ViewStep2"            name="WizardForm"           scope="session"            type="org.apache.struts.actions.ForwardAction"       parameter="/step2.jsp"/> <action    path="/ProcessStep2"            name="WizardForm"           scope="session"            type="com.oreilly.strutsckbk.ch07.WizardLookupDispatchAction"       parameter="methodToCall">     <forward name="previous" path="/ViewStep1.do"/>     <forward name="next" path="/ViewStep3.do"/> </action> <!-- Step 3 --> <action    path="/ViewStep3"            name="WizardForm"           scope="session"            type="org.apache.struts.actions.ForwardAction"       parameter="/step3.jsp"/> <action    path="/ProcessStep3"            name="WizardForm"           scope="session"            type="com.oreilly.strutsckbk.ch07.WizardLookupDispatchAction"       parameter="methodToCall">     <forward name="previous" path="/ViewStep2.do"/>     <forward name="finish" path="/wizard_done.jsp"/> </action>

Discussion

The topic of wizard-style applications comes up frequently on the Struts mailing lists. Struts doesn't have a silver bullet solution for this problem. Wizard interfaces can be built many ways; there is no "right way" to do it. The Solution leverages the ability of the LookupDispatchAction and the use of a session-scoped form to pass data from page to page. If it doesn't meet your needs, it will at least provide the basis of a custom solution.

The WizardLookupDispatchAction subclasses LookupDispatchAction, implementing the getKeyMethodMap( ) method to map a button label key to the corresponding method. Methods are provided for handling previous, next, and finish buttons. Each of these methods delegates processing to a no-op protected method. The business logic for processing the form from each JSP would be added to the processNext( ) method. Business logic required when clicking previous would be implemented in the processPrevious( ) and logic to be handled when clicking finish is implemented in the processFinish( ) method.

A benefit of this Solution is you can see the flow from page to page in the struts-config.xml. You can look at the mappings and follow the steps in the flow:

<forward name="previous" path="/ViewStep1.do"/> <forward name="next" path="/ViewStep3.do"/>

The solution works even if the user clicks the browser's back or forward buttons instead of using the navigation buttons.

One common gripe about the LookupDispatchAction is it doesn't work well if you are using images for buttons. In this case, you may want to extend DispatchAction and set the dispatch action using JavaScript.

See Also

Use of the LookupDispatchAction is presented in Recipe 6.9. The DispatchAction is shown in Recipe 6.8. The basic approach shown here is similar to that presented in the Struts Newbie FAQ at http://struts.apache.org/faqs/newbie.html#wizard.

An extension to Struts for complex workflows has been developed by Matthias Bauer and can be found at http://www.livinglogic.de/Struts/index.html. This extension utilizes a custom ActionMapping and RequestProcessor. In addition to the basic workflow steps discussed in this recipe, it supports workflow branching and custom authentication.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

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