Recipe6.10.Dispatching to Related Operations with Action Mappings


Recipe 6.10. Dispatching to Related Operations with Action Mappings

Problem

You want to use a single Action class to process related operations yet allow the form type, validation rules, and other action attributes to vary for each operation.

Solution

Extend the Struts pre-built MappingDispatchAction (only available in Struts 1.2 or later) with your own subclass. Provide methods for each operation you wish to be callable. Each method should have the same signature as the execute() method. The class shown in Example 6-8 provides three related operations: create( ), update( ), and delete( ).

Example 6-8. MappingDispatchAction for related operations
package com.oreilly.strutsckbk.ch06; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.PropertyUtils; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.actions.MappingDispatchAction; public class MyMappingDispatchAction extends MappingDispatchAction {         public ActionForward create( ActionMapping mapping,                 ActionForm form,                HttpServletRequest request,                 HttpServletResponse response) throws Exception {         PropertyUtils.setSimpleProperty(form, "dispatchedTo", "create");         return mapping.findForward("success");     }             public ActionForward update( ActionMapping mapping,                ActionForm form,               HttpServletRequest request,                HttpServletResponse response) throws Exception {         PropertyUtils.setSimpleProperty(form, "dispatchedTo", "update");         return mapping.findForward("success");     }             public ActionForward delete( ActionMapping mapping,                ActionForm form,               HttpServletRequest request,                HttpServletResponse response) throws Exception {         PropertyUtils.setSimpleProperty(form, "dispatchedTo", "delete");         return mapping.findForward("success");     } }

In the actions that use your MappingDispatchAction, specify the value of the method to call as the value of the parameter attribute. Unlike the DispatchAction and LookupDispatchAction, a different action form, identified by the name attribute, can be specified for each action mapping:

<action    path="/AddAction"            name="AddForm"            type="com.oreilly.strutsckbk.ch06.MyMappingDispatchAction"       parameter="create">   <forward name="success" path="/mapping_dispatch_test.jsp"/> </action> <action    path="/ChangeAction"            name="ChangeForm"            type="com.oreilly.strutsckbk.ch06.MyMappingDispatchAction"       parameter="update">   <forward name="success" path="/mapping_dispatch_test.jsp"/> </action> <action    path="/RemoveAction"            name="RemoveForm"            type="com.oreilly.strutsckbk.ch06.MyMappingDispatchAction"       parameter="delete">   <forward name="success" path="/mapping_dispatch_test.jsp"/> </action>

Reference the path of the action to use as the value for the action attribute on the html:form tag. The JSP in Example 6-9 (mapping_dispatch_test.jsp) contains three separate forms, each corresponding to the three actions defined in the struts-config.xml file.

Example 6-9. JSP that submits to a mapping dispatch action
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head>   <title>Struts Cookbook - Chapter 6 : Mapping Dispatch Action Test</title> </head> <body bgcolor="white"> <h2>Mapping Dispatch Action Test</h2>   <hr />   <h3>Add Action</h3>   <html:form method="get" action="/AddAction">     Name:&nbsp;<html:text property="name"/>     <p><html:submit/></p>   </html:form>   <p>   Name:&nbsp;<c:out value="${AddForm.map.name}"/><br />   Dispatch Method:&nbsp;<b><c:out value="${AddForm.map.dispatchedTo}"/>   </b>   <hr />   <h3>Change Action</h3>   <html:form method="get" action="/ChangeAction">     Name:&nbsp;<html:text property="name"/>     <p><html:submit/></p>   </html:form>   <p>   Name:&nbsp;<c:out value="${ChangeForm.map.name}"/><br />   Dispatch Method:&nbsp;<b><c:out value="${ChangeForm.map.dispatchedTo}"/>   </b>   <hr />   <h3>Remove Action</h3>   <html:link page="/RemoveAction.do?name=Test">Remove Me</html:link>    <p>   Name:&nbsp;<c:out value="${RemoveForm.map.name}"/><br />   Dispatch Method:&nbsp;<b><c:out value="${RemoveForm.map.dispatchedTo}"/>   </b> </body> </html>

Discussion

The MappingDispatchAction, included with Struts 1.2, extends the DispatchAction. Whereas the operational methods implemented in a DispatchAction or LookupDispatchAction are tied to a request parameter, the method to call in a MappingDispatchAction is tied to an action definition in the struts-config.xml file. The parameter attribute of the action element identifies the method to call.

The MappingDispatchAction allows you to group together related methods. However, the ActionForm can vary per method. This allows for greater flexibility when dispatching related operations. You get the benefits of grouping the related operations, yet you aren't required to use a common form if it doesn't make sense. Consider a concrete Action for performing the traditional CRUD functionality. Though the create( ) and update( ) operations most likely use the same ActionForm, the read( ) and delete( ) operations only require a single form property representing the object's primary identifier or key.

Because the form can vary per method, the validation rules can vary since these rules are related to the form type. The MappingDispatchAction provides a more elegant solution than the other DispatchAction types because it doesn't rely on JavaScript or the use of reverse MessageResource lookups. However, this action is new to Struts and is available with Struts Version 1.2 or later.

See Also

If you are using Struts 1.1 and want to use a DispatchAction for related operations, Recipes Section 6.8 and Section 6.9 show how this can be accomplished. A short tutorial on using the MappingDispatchAction can be found in the weblog entry at http://frustratedprogrammer.blogspot.com/2004/07/struts-121-mappingdispatchaction.html. You should also read over the JavaDocs for the MappingDispatchAction. These can be found at http://struts.apache.org/api/org/apache/struts/actions/MappingDispatchAction.html.



    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