Struts Tutorial

Modifying an Application to Use DynaActionForms

In this tutorial we are going to modify our first application (GuessGame) to use a DynaForm instead of a FormBean. You should first create the application following the first tutorial or download this jar file and import it into Struts Studio.

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. This is a neat feature of Struts Studio that verifies your Struts application and notifies you if something is wrong.

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.

itemvalueexplanation
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.
NameType
guessNumber java.lang.String

Now, create the second Form Property. Leave Initial and Size blank.
NameType
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!