Sei sulla pagina 1di 3

STRUTS ACTION - AGGREGATING

ACTIONS IN STRUTS
If you are a Struts developer

then you might have experienced the pain of writing huge number of Action classes for
your project. The latest version of struts provides classes using which you can aggregate
a related set of actions into a single unified action. In this article we will see how to
achieve this. Struts provides four important classes for this purpose. These classes are
called as Dispatchers. The important Dispatchers that struts provides includes :
DispatchAction, ActionDispatcher , LookupDispatchAction and
MappingDispatchAction.

All these classes can be found in the package org.apache.struts.actions. Let us look in to
each of these in detail. Our examples use the simple CRUD actions.

DispatchAction: In this type of aggregation, the action class must extend DispatchAction
class as shown.

public final class CRUDDispatchAction extends DispatchAction {

public ActionForward create(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
return (mapping.findForward("success"));
}
...

and the action mapping will be as

<action path="/crudDispatchAction"
type="com.companyname.projname.CRUDDispatchAction" name="formName"
scope="request" input=" homeDef" parameter="methodToCall">
<forward name="success" path="targetDefName"/>
</action>

in your jsp you can call this action as

<html:link action="crudDispatchAction?methodToCall=create">Create</html:link>
...

Observe that the above class extends DispatchAction and so you cannot use this method
if your class already extends your (some) super class (eg., the class where the session is
validated/invalidated). Here the user has to send a query string variable (methodToCall)
to set the action name to call.

ActionDispatcher: This flavor of aggregation is same as DispatchAction except that we


need not extend ActionDispatcher, so we can use this method even if our class extends a
super class. The following code snippet shows this scenario.

public final class CRUDActionDispatcher extends Action {

protected ActionDispatcher dispatcher = new ActionDispatcher(this,


ActionDispatcher.DEFAULT_FLAVOR);

public ActionForward execute(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
return dispatcher.execute(mapping, form, request, response);
}

The DEFAULT_FLAVOR field suggests that the default parameter is "method" if none
is specified as parameter in struts-config.xml (eg,. methodToCall).
ActionDispatcher flavor also needs methodToCall parameter to be set (using hidden
variable or a query string) as in case of DispatchAction.

LookupDispatchAction: This type of aggregation is useful in situations where in you


have multiple submit buttons in a single form. The class must extend
LookupDispatchAction. However, the great thing about this type is that its java script
free. That means, you need not set any hidden variables or pass query string however,
you must use submit buttons as shown.

<html:submit property="submit"><bean:message key="button.create"/></html: submit >


<html:submit property="submit"><bean:message key="button.read"/></html: submit >
...
The example Action class will be as follows

public class CRUDLookUpDispatchAction extends LookupDispatchAction {

protected Map getKeyMethodMap() {


Map map = new HashMap();
map.put("button.create", "create");

return map;
}
public ActionForward create(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
return (mapping.findForward("success"));
}
Observe the getKeyMethodMap() method. The submit button names are specified in a
Map and their keys comes from MessageResources file. Struts picks up the name from
this file and redirects it to the value specified in the Map. The calling code in jsp however
has multiple submit buttons only differing in their names.

MappingDispatchAction: This aggregation extends MappingDispatchAction class. This


is the most useful type among the four types available. But as seen in other cases, you can
use this type only when your action does not extend any other action. The good thing
about this type is that the action mappings can differ and so need not be the same as in all
other cases. To illustrate this consider the below mappings.

<action path="/createMappingAction"
type="com.bodhtree.CRUDMappingDispatchAction" scope="request" input="homeDef"
parameter="create">
<forward name="success" path="targetDef"/>
</action>
<action path="/readMappingAction"
type="com.bodhtree.CRUDMappingDispatchAction" name=" formName"
scope="request" input="homeDef" parameter=" read">
<forward name="success" path="targetDef"/>
</action>

Notice that in the first action mapping, there is no form bean while in the second the bean
name is specified. This means that the user has the flexibility to change the mapping
according to his needs and hence not been contained to use a constant mapping for all the
CRUD actions. Note that in all the other types of aggregations, we must use the same
mapping for all the CRUD actions.

Conclusion: Each of these types has their own pros and cons. DispatchAction is the
default type which uses java script and we must extend DispatchAction to use it,
ActionDispatcher is same as DispathAction except that we do not extend any action ,
LookupDispatchAction gives the flexibility to use multiple submit buttons while
MappingDispatchAction allows us to change the action mappings according to our need.
So each one of these has a particular usage and which one to use depends on the user
requirement.

Potrebbero piacerti anche