Struts Action class uses a single execute method to handle all user requests. So what do we do when a screen has multiple submit buttons, each performing different operations. For eg:- the CRUD ( create, read, update, delete ) operations for a single entity. A general scenario that I have seen is, you have a List Page from which you can travel to a Detail Page by clicking on the line item link. Detail Page will have Update, Delete and Back buttons. List Page will have create button.

So, do you need to write three action classes for handling these button events. No, there is something called DispatchAction and LookupDispatchAction in struts. The solution that I am going to describe here is based on extending ActionMapping.
The struts-config entry for these usecases will look like this,
<action path=”/displayList”
type=”com.unnisworld.employee.EmployeeAction”
name=”employeeForm”
validate=”false”
className=”com.unnisworld.struts.CustomActionMapping”>
<set-property property=”method” value=”doDisplayList” />
<forward name=”success” path=”/WEB-INF/pages/employee/list.jsp”/>
</action>
<action path=”/create”
type=”com.unnisworld.employee.EmployeeAction”
name=”employeeForm”
validate=”false”
className=”com.unnisworld.struts.CustomActionMapping”>
<set-property property=”method” value=”create” />
<forward name=”success” path=”/WEB-INF/pages/employee/list.jsp”/>
</action>
<action path=”/displayUpdate”
type=”com.unnisworld.employee.EmployeeAction”
name=”employeeForm”
validate=”false”
className=”com.unnisworld.struts.CustomActionMapping”>
<set-property property=”method” value=”doDisplayUpdate” />
<forward name=”success” path=”/WEB-INF/pages/employee/employee.jsp”/>
</action>
<action path=”/update”
type=”com.unnisworld.employee.EmployeeAction”
name=”employeeForm”
validate=”false”
className=”com.unnisworld.struts.CustomActionMapping”>
<set-property property=”method” value=”update” />
<forward name=”success” path=”/WEB-INF/pages/employee/list.jsp”/>
</action>
<action path=”/delete”
type=”com.unnisworld.employee.EmployeeAction”
name=”employeeForm”
validate=”false”
className=”com.unnisworld.struts.CustomActionMapping”>
<set-property property=”method” value=”delete” />
<forward name=”success” path=”/WEB-INF/pages/employee/list.jsp”/>
</action>
Only new thing in these action mapping entries are the set-property tags and the className attribute. The “method” property is not part of the standard struts ActionMapping class. You need to write a custom action mapping class to hold this property. This custom class is specified using the className attribute.
package com.unnisworld.struts;
import org.apache.struts.action.ActionMapping;
public class CustomActionMapping extends ActionMapping {
private static final long serialVersionUID = 1L;
private String method;
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
}
Now you need to write a top level action class which all other action classes in your project will extend.
This action class will have the logic to get the method name property from ActionMapping and invoke the correct method.
package com.unnisworld.struts;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.*;
import org.apache.struts.actions.DispatchAction;
/**
* Extends DispatchAction, actual logic for invoking action methods using reflection
* resides in the DispatchAction. We just need to override getMethodName function.
*/
public class BaseAction extends DispatchAction {
/**
* This is the only execute method in the entire action class hierarchy.
*/
public final ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
beforeExecute(mapping, form, request, response);
ActionForward af = super.execute(mapping, form, request, response);
afterExecute(mapping, form, request, response);
return af;
}
/**
* This method returns the method name from ActionMapping class.
* DispatchAction class uses this method to get the method name.
*/
protected String getMethodName(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response,
String parameter) throws Exception
{
return ((CustomActionMapping) mapping).getMethod();
}
/**
* This method is not used, but must be implemented to satisfy DispatchAction.
*/
protected String getParameter(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
return “nothing”;
}
protected void beforeExecute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
{
}
protected void afterExecute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
{
}
}
The BaseClass extends DispatchAction which has the logic to invoke methods using reflection. We just need to implement getMethodName method. beforeExecute and afterExecute are hook methods which can be overridden and used for initialization and cleanup operations.
Now look at CustomerAction which extends the BaseAction. It does not have execute method, instead it has methods like doDisplayList, create, update etc which are same as the method names given in struts-config file.
public class CustomerAction extends BaseAction {
public final ActionForward doDisplayList(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
}
public final ActionForward create(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
}
public final ActionForward doDisplayUpdate(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
}
public final ActionForward update(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
}
}
Now there is a crucial javascript part that is required to switch the action in EmployeeUpdate screen.
On the onClick event of Update and Delete buttons you should assign the correct action name to html form.
<script>
function switchAction(action) {
document.forms[0].action =action;
document.forms[0].submit();
}
<script>
<input type=”button” onClick=”switchAction(‘update’)” value=”Update” />
<input type=”button” onClick=”switchAction(‘delete’)” value=”Delete” />
Note :- This solution is a slight variation of the DispatchAction solution specified at struts site.