Struts2: method attribute in <s: submit> not working
I have a form in jsp. There are two submit buttons: the Search button and the Add New button. I set each button with its own method attribute.
<s:form name="searchForm" action="employeeAction" method="post"> <s:textfield name="id" label="Employee ID"/> <s:textfield name="name" label="Employee Name"/> <s:submit value="Search" method="doSearch"/> <s:submit value="Add New" method="doAddNew"/> </s:form> In struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default"> <default-action-ref name="index" /> <global-results> <result name="error">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error"/> </global-exception-mappings> </package> <package name="example" namespace="/example" extends="default"> <action name="employeeAction" class="example.EmployeeAction"> <result name="search">/example/search.jsp</result> <result name="add">/example/add.jsp</result> </action> </package> </struts> In class EmployeeAction
public class EmployeeAction extends ActionSupport { private static final Logger logger = Logger.getLogger(EmployeeAction.class); @Override public String execute() throws Exception { logger.info("Calling execute!"); return SUCCESS; } public String doSearch() throws Exception { logger.info("Calling doSearch!"); return "search"; } public String doAddNew() throws Exception { logger.info("Calling doAddNew!"); return "add"; } } The problem is that I clicked the Search or Add New button, the doSearch () or doAddNew () method was never called, instead it called the execute () method. What is wrong with my code above?
I am using struts v2.3.
Set
<constant name="struts.enable.DynamicMethodInvocation" value="false" /> to
<constant name="struts.enable.DynamicMethodInvocation" value="true" /> Another way is to define multiple mappings for the same Action, for example
in JSP:
<s:submit value="Search" action="employeeSearchAction" /> <s:submit value="Add New" action="employeeAddNewAction"/> in struts.xml
<action name="employeeSearchAction" class="example.EmployeeAction" method="doSearch"> <result>/example/search.jsp</result> </action> <action name="employeeAddNewAction" class="example.EmployeeAction" method="doAddNew"> <result>/example/add.jsp</result> </action> The third way is to use wildcards .
PS: If you move on to the second, I suggest, as a best practice, use one action for each logical action that you must perform ...
If you have common data loaded / managed by both of your actions, βsearchβ and βaddNewβ, then you can define employeeBaseAction extended by both employeeSearchAction and employeeAddNewAction.
EDIT
It is now 2014, and the use of DMI is unanimously discouraged (today more than ever), except quite useless, so I strongly suggest you use the solution n.2.