The ActionForm


The ActionForm

The JSP pages and ActionForm beans work hand-in-hand in Struts because the JSP submits the user input to the bean, and the bean returns validation errors to the JSP.

To understand how they work together, take a look at one ActionForm and the JSP page it relates to. Listing 7.1 shows the NewUserForm bean, which is the ActionForm for the create account screen of the application.

Note

This file is available on the companion CD with this book.


Listing 7.1 NewUserForm.java
 package stocktrack.struts.form; import javax.servlet.http.*; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionForm; import stocktrack.struts.form.BaseForm; /**  * stocktrack.struts.form.NewUserForm class.  * this class used by Struts Framework to store data from newUserForm  *  * struts-config declaration:  * <form-bean name="newUserForm"  *         type="stocktrack.struts.form.NewUserForm" />  *  * @see org.apache.struts.action.ActionForm org.apache.struts.action.ActionForm  * Generated by StrutsWizard.  */ public class NewUserForm extends BaseForm {   public void reset(ActionMapping mapping, HttpServletRequest request) {     username = "";     password = "";     firstName = "";     lastName = "";     streetAddress1 = "";     streetAddress2 = "";     city = "";     state = "";     postalCode = "";     homePhone = "";     workPhone = "";     workExt = "";     alert = "";   }   public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {     ActionErrors errors = new ActionErrors();     if (this.isBlankString(username)) {         errors.add("username", new ActionError("stocktrack.newuser.required"));     }     if (this.isBlankString(password)) {         errors.add("password", new ActionError("stocktrack.newuser.required"));     }     if (this.isBlankString(email)) {         errors.add("email", new ActionError("stocktrack.newuser.required"));     } else {         if (email.indexOf("@") == -1) {         errors.add("email", new ActionError("stocktrack.newuser.invalid.email"));         }     }     if (this.isBlankString(firstName)) {         errors.add("firstName", new ActionError("stocktrack.newuser.required"));     }     if (this.isBlankString(lastName)) {         errors.add("lastName", new ActionError("stocktrack.newuser.required"));     }     if (this.isBlankString(streetAddress1)) {         errors.add("streetAddress1",                    new ActionError("stocktrack.newuser.required"));     }     if (this.isBlankString(city)) {         errors.add("city", new ActionError("stocktrack.newuser.required"));    }     if (this.isBlankString(state)) {         errors.add("state", new ActionError("stocktrack.newuser.required"));    } else {       if (!this.isValidState(state)) {         errors.add("state", new ActionError("stocktrack.newuser.invalid.state"));       }    }     if (this.isBlankString(postalCode)) {         errors.add("postalCode", new ActionError("stocktrack.newuser.required"));    } else {      if (!this.isValidPostalCode(postalCode)) {          errors.add("postalCode",                     new ActionError("stocktrack.newuser.invalid.postalCode"));      }     }     if (this.isBlankString(homePhone)) {         errors.add("homePhone", new ActionError("stocktrack.newuser.required"));     } else {         if (!this.isValidPhone(homePhone)) {           errors.add("homePhone",                      new ActionError("stocktrack.newuser.invalid.phone"));         }     }     if (this.isBlankString(workPhone)) {         errors.add("workPhone", new ActionError("stocktrack.newuser.required"));     } else {         if (!this.isValidPhone(workPhone)) {           errors.add("workPhone",                      new ActionError("stocktrack.newuser.invalid.phone"));         }     }     return errors;   }   private String username;   private String password;   private String email;   private String firstName;   private String lastName;   private String streetAddress1;   private String streetAddress2;   private String city;   private String state;   private String postalCode;   private String homePhone;   private String workPhone;   private String workExt;   private String alert;   public String getUsername() {     return username;   }   public void setUsername(String username) {     this.username = username;   }   public String getPassword() {     return password;   }   public void setPassword(String password) {     this.password = password;   }   public String getEmail() {     return email;   }   public void setEmail(String email) {     this.email = email;   }   public String getFirstName() {     return firstName;   }   public void setFirstName(String firstName) {     this.firstName = firstName;   }   public String getLastName() {     return lastName;   }   public void setLastName(String lastName) {     this.lastName = lastName;   }   public String getStreetAddress1() {     return streetAddress1;   }   public void setStreetAddress1(String streetAddress1) {     this.streetAddress1 = streetAddress1;   }   public String getStreetAddress2() {     return streetAddress2;   }   public void setStreetAddress2(String streetAddress2) {     this.streetAddress2 = streetAddress2;   }   public String getCity() {     return city;   }   public void setCity(String city) {     this.city = city;   }   public String getState() {     return state;   }   public void setState(String state) {     this.state = state;   }   public String getPostalCode() {     return postalCode;   }   public void setPostalCode(String postalCode) {     this.postalCode = postalCode;   }   public String getHomePhone() {     return homePhone;   }   public void setHomePhone(String homePhone) {     this.homePhone = homePhone;   }   public String getWorkPhone() {     return workPhone;   }   public void setWorkPhone(String workPhone) {     this.workPhone = workPhone;   }   public String getWorkExt() {     return workExt;   }   public void setWorkExt(String workExt) {     this.workExt = workExt;   } } 

This ActionForm bean (and most of the other Struts- related files in the application) were generated using the excellent Struts Wizard for JBuilder, which automatically generates ActionForm s, Action s, and JSP files for Struts.

The bottom of the file can be ignored for the most part. It contains the get and set methods for the bean properties, just as in any other JavaBean. The two interesting methods of the class are reset() and validate() .

The reset() method is called when a form is initialized before being used by Struts. It's responsible for clearing all the bean properties back to their initial state values. This method can also be used to provide a default value for a property.

The validate() method is the real heart of an ActionForm . It looks at all the user input to the form, and makes sure that it is consistent with the data that the application requires.

You might notice that this bean does not directly extend ActionForm , but instead extends BaseForm . BaseForm is a class that extends ActionForm and provides a number of useful helper functions for validation, such as isValidPostalCode . Listing 7.2 shows the source for BaseForm .

Listing 7.2 BaseForm.java
 package stocktrack.struts.form; import org.apache.struts.action.ActionForm; import org.apache.regexp.*; import java.util.Vector; /**  * <p>Title: Stock Tracking Application</p>  * <p>Description: Example application from the book: Struts - Rapid Working Knowledge</p>  * <p>Copyright: Copyright (c) 2002</p>  * <p>Company: </p>  * @author James Turner and Kevin Bedell  * @version 1.0  */ public class BaseForm extends ActionForm {   protected boolean isBlankString(String str) {       if (str == null) return true;       return (str.length() == 0);   }   protected boolean isValidPostalCode(String str) {   try {       RE postal = new RE("\d\d\d\d\d(\-\d\d\d\d)?");       return (postal.match(str));   } catch (Exception ex) {       ex.printStackTrace();       return false;   }   } protected boolean isDouble(String str) {   try {       Double.parseDouble(str);       return true;   } catch (Exception ex) {       return false;     }   }   protected boolean isValidPhone(String str) {   try {       RE phone = new RE("\(?\d\d\d\)? *\-? *\d\d\d *\-? *\d\d\d\d");       return (phone.match(str));   } catch (Exception ex) {       ex.printStackTrace();       return false;   }   }   protected String states[] = {"AL","AK","AS","AZ","AR","CA","CO","CT","DE",                                "DC","FM","FL","GA","GU","HI","ID","IL","IN",                                "IA","KS","KY","LA","ME","MH","MD","MA","MI",                                "MN","MS","MO","MT","NE","NV","NH","NJ","NM",                                "NY","NC","ND","MP","OH","OK","OR","PW","PA",                                "PR","RI","SC","SD","TN","TX","UT","VT","VI",                                "VA","WA","WV","WI","WY"};   protected boolean isValidState(String str) {     for (int i = 0; i < states.length; i++) {       if (states[i].equalsIgnoreCase(str)) return true;     }     return false;   } } 

The validate() method is passed two arguments: the ActionMapping for the action (which will be discussed in the next chapter) and the HttpServletRequest . In most cases, the validate() method needs neither of these values, but must take them to match the signature. The method returns an ActionError s object, which is a collection of all the ActionError objects created during validation.

In this class, the method first instantiates an ActionError s object, storing it in errors . The method proceeds to validate each property in turn . If the property doesn't validate (because of an empty required field, for example), the code creates a new ActionError object and uses the add() method on errors to associate the error with a field.

The add() method takes two arguments. The first argument should match the property name of the field as used in the form. For example, if the bean supplies the get method getUsername() , the property name that should be used on the form and as the first argument to ActionError.add should be username . This is the standard JavaBean/JSP convention.

The second argument passed to add() is an ActionError . This class is really just an error message to be passed back to the form, but it is designed so that the error messages come from the application property file instead of a fixed string. This enables nondevelopers to maintain the text of the errors messages, and also automatically makes the error messages "internationalizable" because the application property file can be customized to different locales.

Listing 7.3 shows the portion of ApplicationResources.properties that holds the error messages for this form.

Listing 7.3 A Portion of ApplicationResources.properties
[View full width]
 stocktrack.newuser.required=REQUIRED FIELD stocktrack.newuser.invalid.phone=(NNN) NNN-NNNN stocktrack.newuser.invalid.state=No such state stocktrack.newuser.invalid.postalCode=NNNNN or NNNNN-NNNN stocktrack.newuser.duplicate.user=The username you requested is already in use, please graphics/ccc.gif try another one 

After all the validations have been run, the validate() method returns the ActionError s object. If it contains no errors, the controller runs the Action associated with the form. If there were validation errors, control is returned to the JSP, which is responsible for displaying the error messages.

VALIDATING BUSINESS LOGIC

Sometimes there are validations that need to run on a form, but require business logic to determine whether the field or form is valid. For example, in the create account processing, the code must determine whether the username is already in use, because it must be unique.

To be consistent with the MVC design pattern, however, you should never place business logic in an ActionForm because the ActionForm is part of the view. Views are not supposed to contain any actual knowledge of the back end. This information lives in the model.

In Struts, the Action provides the interface between the View and the Model. As you'll see in Chapter 8, "The Controller: Directing the Action," there are ways to do validations inside the Action as well as in the ActionForm .



Struts Kick Start
Struts Kick Start
ISBN: 0672324725
EAN: 2147483647
Year: 2002
Pages: 177

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net