What is DynaActionForm?
Suppose we have lots of JSP pages with forms that we want to validate. We could write an ActionForm with getter/setter pairs for each of the JSP pages, but, if we had 20 pages, we would have to write an ActionForm for each one. This is inconvenient.
Instead, we can create a single DynaActionForm. A DynaActionForm can be reused in any number of Actions. A DynaActionForm will list all possible properties with their types that can appear on a Jsp page. This will become more clear as we actually start creating the DynaActionForm.
Modifying the Application
Open struts-config.xml. Your Web Flow should look like the image below. If you have already added error checking, that’s fine too.
Deleting old ActionForm
Before we can create our DynaActionForm, we need to delete our existing ActionForm. To do this, select the Tree tab of the Web Flow diagram. This view shows a tree-like structure of your struts-config.xml file. Then, right-click struts-config.xml/form-beans/MakeGuessForm and select Delete.
Good. We just deleted our ActionForm. Go ahead and save project changes.
If you look in the Output Window, you should see a message like the one below.
In our case, there is a reference in the /makeGuess Action to our old MakeGuessForm ActionForm. Because we just deleted it, verification has found this error, but we are going to fix it right away.
The action has a Java file, MakeGuessForm.java, associated with it. We can just leave this file or delete it since we are not going to use it in our application.
Creating a DynaActionForm
In the Tree view of the Web Flow diagram, right-click form-beans and select Create Form Bean… . This is the same mechanism used for creating an ActionForm bean, but here we will make it a different type.
| item | value | Explanation |
|---|---|---|
|
Name |
MakeGuessForm |
This is just the name of the DynaActionForm. We will keep the same name because we have a reference to this name in our Action class. You can write a different name, MakeGuessDynaForm, for example, but then don’t forget to modify the reference in the Action. |
| Type | org.apache.struts.action.DynaActionForm |
Not our own type anymore but one from the Struts framework. |
Click Finish and Save. Notice that the error message in the Output Window has disappeared. The reference in the Action points to this newly created DynaActionForm.
Creating Form Attributes
Right-click MakeGuessForm and select Create From Property…. This will create form properties that correspond to the fields on the JSP page. In our case only guessNumber is present on a JSP page. isBigger is not on the the JSP page, but is used to keep track of whether the user guesses correctly.
Create the first Form Property. Leave Initial and Size blank.
| Name | Type |
|---|---|
| guessNumber | java.lang.String |
Now, create the second Form Property. Leave Initial and Size blank.
| Name | Type |
|---|---|
| isBigger | java.lang.Boolean |
The result should be like the image below. 
We are actually almost done. We just need to make minor changes to the MakeGuessAction.java Java source file, so that it will use our newly created DynaActionForm.
Modifying MakeGuessAction.java
The changes we will make to the Java code appear in blue.
package sample; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; // need for Session object import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.DynaActionForm; // DynaActionForm import public class MakeGuessAction extends org.apache.struts.action.Action { // Global Forwards public static final String GLOBAL_FORWARD_start = "start"; // Local Forwards // local forwards generated by Struts Studio // making an error in Forward names is a common mistake // Struts Studio minimizes such errors by generating local Forwards names for you public static final String FORWARD_match = "match"; public static final String FORWARD_nomatch = "nomatch"; public MakeGuessAction() { } public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // retrieve user entered value on the page from DynaActionForm // instead of our own form. DynaActionForm daf = (DynaActionForm)form; // because DynaActionForm does not have getters/setters method, // we need to retrieve object values by using get() with the name of form property int userGuess = Integer.parseInt( (String)daf.get("guessNumber") ); // get this session HttpSession session = request.getSession(); // retrieve the generated number, if not running for first time Object genNumberObj = session.getAttribute("applGeneratedNumber"); int generated; // check if generated number was created, if null, it means you are running for the first time if(genNumberObj==null) { generated = (int)(Math.random()*100); // generate number between 0 and 100 // save the number in this session session.setAttribute("applGeneratedNumber",new Integer(generated)); } else { // if number already exists, get the number generated = ((Integer)genNumberObj).intValue(); } // compare numbers, if equal, forward to FORWARD_match resource // if not, forward to FORWARD_nomatch if ( userGuess != generated) { // we use set() method to set the value of isBigger in the // DynaActionForm, by supplying form property name (isBigger) and its value daf.set("isBigger", new Boolean(userGuess > generated)); return mapping.findForward(FORWARD_nomatch); } else { // if we guess the number and want to play a new game, kill // the current session so that we start with a new one session.invalidate(); return mapping.findForward(FORWARD_match); } } }
Once we make these changes and save the file, we are done. Now we only need to recompile, start (or restart) Tomcat or JBoss and run the updated application. To build the updated application, right-click ant/build.xml and select Run Ant… . The build target should be checked. Click Run. Next, start the Tomcat server (or restart if Tomcat was running). Then, on the Web Flow diagram, right-click the Global Foward called start and select Run. Now the application is running and using our newly created DynaActionForm!



