11.4 Creating Your Own Validation Rules

The Validator framework is preconfigured with many of the most common rules that you're likely to need for your Struts applications. If your application has validation requirements that are not met by the default rules, you have complete freedom to create your own. There are several steps that you must follow, however, to create your own customized rules:

1.       Create a Java class that contains the validation methods.

2.       Edit the validation-rules.xml file or create your own version. If you do create a new validation resource file, be sure to add it to the list of resource files in the Validator plug-in.

3.       Use the new validation rules in the validation.xml file for your application.

Each validation method you create must have the following signature:

public static boolean validateXXX( java.lang.Object,
                                   org.apache.commons.validator.ValidatorAction,
                                   org.apache.commons.validator.Field,
                                   org.apache.struts.action.ActionErrors,
                                   javax.servlet.http.HttpServletRequest,
                                   javax.servlet.ServletContext );

where validateXXX can be whatever you want it to be, as long as it's not a duplicate rule name. Table 11-3 explains the arguments to the validateXXX( ) method.

Table 11-3. The validateXXX( ) method arguments

Parameter

Description

Object

The JavaBean on which validation is being performed

ValidatorAction

The current ValidatorAction being performed

Field

The field object being validated

ActionErrors

The errors objects to add an ActionError to if the validation fails

HttpServletRequest

The current request object

ServletContext

The application's ServletContext

In most cases, the method should be static. However, you can define instance-level methods as well. Regardless of whether your methods are static, you must ensure that they are thread-safe. Example 11-3 illustrates a new validation rule that validates whether a String value is a valid boolean.

Example 11-3. A validation rule that validates a boolean value
import java.io.Serializable;
import java.util.Locale;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericTypeValidator;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.util.StrutsValidatorUtil;
 
public class NewValidator implements Serializable {
  /**
   * A validate routine that ensures the value is either true or false.
   */
  public static boolean validateBoolean( Object bean, ValidatorAction va,
    Field field, ActionErrors errors, HttpServletRequest request ) {
 
    String value = null;
    // The boolean value is stored as a String
 
    if (field.getProperty() != null && field.getProperty().length(  ) > 0){
      value = ValidatorUtil.getValueAsString(bean, field.getProperty(  ) );
    }
 
 
    Boolean result = Boolean.valueOf(value);
    if ( result == null ){
      errors.add( field.getKey(  ),
                  StrutsValidatorUtil.getActionError(request, va, field));
    }
 
    // Return true if the value was successfully converted, false otherwise
    return (errors.empty(  ));
  }
}

The next step is to add this new rule to the validation-rules.xml file, or to a new file to keep your customized rules separate. The validator element for the validateBoolean rule should look something like:

<validator name="boolean"
  classname="NewValidator"
  method="validateBoolean"
  methodParams="java.lang.Object,
    org.apache.commons.validator.ValidatorAction,
    org.apache.commons.validator.Field,
    org.apache.struts.action.ActionErrors,
    javax.servlet.http.HttpServletRequest"
  msg="errors.boolean">

The final step is to use the new validation rule in the validation.xml file. This involves creating a field element that matches a boolean property on an ActionForm:

<field property="sendEmailConfirmation" depends="boolean">
   <arg0 key="label.emailconfirmation"/>
</field>