Struts DynaActionForm is a feature that enables the creation of ActionForm beans, dynamically, through XML configuration. In these types of applications, Form beans are virtual instead of hard coded java ActionForm classes. This removes the tedious process of creating and managing ActionForm classes within a project. Configuring a DynaActionForm is pretty simple. Here is a simple DynaActionForm configuration snippet from the struts-config.xml
Listing 1: DynaActionForm
<form-beanname="dynaUserInformationForm" type="org.apache.struts.action.DynaActionForm"> <form-propertyname="username"type="java.lang.String"/> <form-propertyname="password"type="java.lang.String"/> </form-bean>
The above DynaActionForm has two properties - username and password - and both of them are of the type java.lang.String.
Difference between DynaActionForm and ActionForm:
Following is a simple DynaActionForm application based on the Login Application we created in the previous tutorial.
Listing 2: struts-config.xml
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd"> <struts-config> <form-beans> <!--<form-bean name="userInformationForm" type="com.src.loginapp.form.UserInformationForm"/>--> <form-beanname="userInformationForm" type="org.apache.struts.action.DynaActionForm"> <form-propertyname="username"type="java.lang.String"/> <form-propertyname="password"type="java.lang.String"/> </form-bean> </form-beans> <action-mappings> <action path="/LoginPage" type="org.apache.struts.actions.ForwardAction" parameter="/pages/login.jsp"/> <actionpath="/Login" type="com.src.loginapp.action.UserAction" name="userInformationForm"> <forwardname="success"path="/pages/welcome.jsp"/> <forwardname="failure"path="/pages/login.jsp"/> </action> </action-mappings> <message-resources parameter="com.src.loginapp.common.properties.Common"/> </struts-config>
The DynaActionForm is configured under the form-beans section just as with the ActionForm configurations. The form bean becomes a DynaActionForm by having the type as org.apache.struts.action.DynaActionForm. In the above example the name of the DynaActionForm bean is dynaUserInformationForm that has two properties - username and password - both of which are of type java.lang.String.
The struts-config.xml is also configured to have action mappings like the application in the previous tutorial.
Listing 3: UserAction.java
packagecom.src.loginapp.action;
importjava.util.ArrayList;
importjava.util.List;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.struts.action.Action;
importorg.apache.struts.action.ActionForm;
importorg.apache.struts.action.ActionForward;
importorg.apache.struts.action.ActionMapping;
importorg.apache.struts.action.DynaActionForm;
public class UserAction extends Action{
publicActionForward execute(ActionMappingmapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception {
//UserInformationFormuserInformationForm = (UserInformationForm) form;
DynaActionFormuserInformationForm = (DynaActionForm)form;
List errorList = new ArrayList();
// check if username is empty
//if (userInformationForm.getUsername() == null || "".equals(userInformationForm.getUsername().trim())){
if(userInformationForm.get("username") == null ||
("" .equals((( String )userInformationForm .get( "username" )) .trim()))) {
// set error message
errorList .add(new String( "Please enter Username" ));
request .getSession() .setAttribute( "errorList" , errorList);
//stay in login page
returnmapping.findForward("failure");
}
// check if password is empty
//else if (userInformationForm.getPassword() == null || "".equals(userInformationForm.getPassword().trim())) {
else if( userInformationForm .get("password") == null ||
("".equals((( String ) userInformationForm .get("password")) .trim()))) {
// set error message
errorList.add(new String("Please enter Password"));
request .getSession() .setAttribute( "errorList" , errorList);
// stay in login page
return mapping .findForward("failure");
}
// forward to welcome page
return mapping .findForward("success");
}}
The above code shows how to use DynaActionForm. With a normal ActionForm, getters and setters will be used to access data from the Form bean. However, in the case of DynaActionForm, the bean’s get() and set() methods will have to be used. Since we do not a hard coded Form bean class, all the Form class validation will be performed in the Action class.
Struts DispatchAction comes in handy when there is more than one action to be performed through a single jsp. Struts DispatchAction enables grouping of multiple functions in a single action class. This results in better maintenance and improved coding flexibility. With a normal Struts action class, all the logic needs to go into the single execute() method. No matter how many buttons the JSP has, all the actions are directed to the single execute() method. Having just one execute() method means that there will be increased conditional checks to incorporate multiple logic. Having one huge execute() method can become rather tedious. This is where DispatchAction comes to help. DispatchAction allows for multiple methods to be created within the same Action class. The distinguished methods can be invoked by means of a parameter that carries the method name.
In this tutorial, the Login Application will be extended to include DispatchAction instead of the regular Action class. In this example, the login.jsp will have two submit buttons - one for login and one for reset. Both buttons should access the Action class to perform the corresponding action.
For ease of creating and comparing, a new Action class is created with the name LoginDispatchAction.java. The UserAction.java class from the previous tutorial is left untouched.
Listing 4: UserAction.java
packagecom.src.loginapp.action;
importjava.util.ArrayList;
importjava.util.List;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.struts.action.ActionForm;
importorg.apache.struts.action.ActionForward;
importorg.apache.struts.action.ActionMapping;
importorg.apache.struts.actions.DispatchAction;
importcom.src.loginapp.form.UserInformationForm;
public class LoginDispatchAction extends DispatchAction{
publicActionForwardloginUser(ActionMappingmapping,ActionForm form,
HttpServletRequestrequest,HttpServletResponse response)
throws Exception {
UserInformationFormuserInformationForm = (UserInformationForm) form;
List errorList = new ArrayList();
// check if username is empty
if (userInformationForm.getUsername() == null || "".equals(userInformationForm.getUsername().trim())){
// set error message
errorList .add(new String( "Please enter Username" ));
request .getSession() .setAttribute( "errorList" , errorList);
//stay in login page
return mapping.findForward("failure");
}
// check if password is empty
else if (userInformationForm.getPassword() == null || "".equals(userInformationForm.getPassword().trim())) {
// set error message
errorList.add(new String("Please enter Password"));
request .getSession() .setAttribute( "errorList" , errorList);
// stay in login page
return mapping .findForward("failure");
}
// forward to welcome page
return mapping .findForward("success");
}
publicActionForwardresetForm(ActionMappingmapping,ActionForm form,
HttpServletRequestrequest,HttpServletResponse response)
throws Exception {
UserInformationFormuserInformationForm = (UserInformationForm) form;
userInformationForm.setUsername("");
userInformationForm.setPassword("");
request .getSession() .removeAttribute( "errorList" );
returnmapping.findForward("success");
}
}
The first major difference between the Action class for DispatchAction and regular Action is the class they inherit from. DispatchAction extends from org.apache.struts.actions.DispatchAction, while a regular Action extends from org.apache.struts.actions.Action.The LoginDispatchAction includes two methods - loginUser() and resetForm(). Both methods have the same method signature, taking 4 parameters - ActionMapping, ActionForm, HttpServletRequest, and HttpServletResponse
The method loginUser() performs the normal username and password validations. The method resetForm() clears the field values and removes the errorList from the session.
Listing 5: struts-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd"> <struts-config> <form-beans> <form-bean name="userInformationForm" type="com.src.loginapp.form.UserInformationForm"/> </form-beans> <action-mappings> <action scope="request" path="/Login" type="com.src.loginapp.action.LoginDispatchAction" name="userInformationForm" parameter="method"> <forward name="success" path="/pages/welcome.jsp"/> <forward name="failure" path="/pages/login.jsp"/> </action> </action-mappings> </struts-config>
The property attribute=”method” signifies the parameter name that will carry the method name to be invoked.
Listing 6: login.jsp
<%@tagliburi="http://struts.apache.org/tags-html" prefix="html"%>
<%@tagliburi="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ tagliburi="http://struts.apache.org/tags-logic" prefix="logic" %>
<html>
<head>
<script type="text/javascript">
function login(){
document.forms[0].action = "Login.do?method=loginUser";
document.forms[0].submit();
}
</script>
</head>
<body>
<h1>Struts Login Application</h1>
<html:form action="Login" >
<div style="padding:16px">
<logic:present name="errorList">
<logic:iterate id="error" name="errorList">
<p style="color:red"><bean:write name="error"/></p>
</logic:iterate>
</logic:present>
</div>
<div style="padding:16px">
User Name
<html:text property="username" size="20" maxlength="20"/>
<br></br>
Password
<html:password property="password" size="20" maxlength="20" />
</div>
<div style="padding:16px">
<div style="float:left;padding-right:8px;">
<html:submitonclick="javascript:login();" value="LOGIN"></html:submit>
<html:submit property="method" value="resetForm"></html:submit>
</div>
</div>
</html:form>
</body>
</html>
The two buttons in the login.jsp invoke two different methods in the LoginDispatchAction class based on the parameter value for the parameter “method”.
<html:submit property="method" value="resetForm"></html:submit>
Here, the resetForm button invokes the resetForm() method in the LoginDispatchAction class. The property attribute signifies the query parameter value as defined in the struts-config.xml. The only drawback here is the value attribute must be equal to method name in the DispatchAction class. The value attribute is case and space sensitive.
This drawback can be overcome by using javascript to set the parameter value. The login button uses javascript to set the parameter value.
<html:submitonclick="javascript:login();" value="LOGIN"></html:submit>
Note here that because javascript is used to set the parameter value, the value attribute in the html:submit button can be anything and doesn’t have to match the java method name in the DispatchAction class.
This is all for today’s article. See you next time.








See the prices for this post in Mr.Bool Credits System below: