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: <html:text property="name"/>
<p><html:submit/></p>
</html:form>
<p>
Name: <c:out value="${AddForm.map.name}"/><br />
Dispatch Method: <b><c:out value="${AddForm.map.dispatchedTo}"/>
</b>
<hr />
<h3>Change Action</h3>
<html:form method="get" action="/ChangeAction">
Name: <html:text property="name"/>
<p><html:submit/></p>
</html:form>
<p>
Name: <c:out value="${ChangeForm.map.name}"/><br />
Dispatch Method: <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: <c:out value="${RemoveForm.map.name}"/><br />
Dispatch Method: <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.
|