Introduction


Ensuring that users enter data correctly can make the difference between a production-ready application and one relegated to remain in the Quality Assurance department. Web applications need to verify the data entered is valid. Data validation takes two forms: syntactic and semantic. Syntactic validity indicates the data is in the correct format; for example, making sure that a numeric field contains only numeric digits. Semantic validity indicates the data means what it should in the functional context of the application. For example, if a user enters his or her birthdate, that date can't be in the future.

The recipes in this chapter cover some advanced uses of the Struts Validator. Some of the recipes use new features of the Validator such as the validwhen validator. A validator is a reusable type of validation. Several recipes show you how easy it is to create your own validators. Providing locale-specific validators to support internationalization is covered. If you're familiar with the Validator, skip ahead to the particular recipes that interest you.

Struts was designed from the beginning to support validation. Every Struts ActionForm has a validate() method.

If a validation check requires access to a back-end business service, like an EJB or the database, place the call to the business service in the Action that processes the form and not the ActionForm itself.


You can add your own data validation checks for form data in this method. The method returns an ActionErrors object, a collection of ActionError objects.

In Struts 1.2, the ActionError class has been deprecated and replaced by the ActionMessage class. The ActionErrors class, however, isn't deprecated. In Struts 1.2, ActionErrors contain a collection of ActionMessage objects. See Recipe 9.5 for more details.


If your validate( ) method returns an ActionErrors object with one or more errors, then the validation check fails. Struts routes control back to the page set as the value for the input attribute of the action element in the struts-config.xml. Example 8-1 shows a simple ActionForm that validates that the username and password fields each have a non-blank value; in other words, they are required.

Example 8-1. Custom action form with validation
package com.oreilly.strutsckbk.ch08; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; public class MyLoginForm extends ActionForm {     public String getPassword( ) {         return password;     }     public void setPassword(String password) {         this.password = password;     }     public String getUsername( ) {         return username;     }     public void setUsername(String username) {         this.username = username;     }          public ActionErrors validate(ActionMapping mapping,          HttpServletRequest request) {         ActionErrors errors = new ActionErrors( );         if (username == null || "".equals(username)) {             errors.add("username",                   new ActionError("errors.required","The username"));         }         if (password == null || "".equals(password)) {             errors.add("password",                  new ActionError("errors.required","The password"));         }         return errors;     }     private String username;     private String password; }

Basic syntax checks, such as those shown in Example 8-1, comprise the vast majority of validation needs. Coding each one of these checks in Java can be tedious and repetitive. Thankfully, the Struts Validator, available to Struts applications since Struts 0.5, has been developed under the Jakarta Commons project.

Struts provides an integration layer with the Validator, which allows you to define validations for form fields in an XML file. You use the Validator for JavaScript-based client-side checks as well as server-side ones. You can write your own validators (see Recipe 8.7); however, the Validator bundles a full-featured set of validators, as shown in Table 8-1 .

Table 8-1. Bundled pluggable validators

required

Checks that a field value is non-null and not an empty string.

requiredif

Only available for Struts 1.1. This validator allows one field to be specified as required if another field is null, not null, or equal to a specified value. This validator is deprecated, in favor of validwhen, in releases after Struts 1.1.

validwhen

Designed to replace requiredif, this validator is available in releases after Struts 1.1. This validator relies on a user-specified test expression that can include references to other fields, field values, and logical relationships.

minlength

Checks that the number of characters in the field value is greater than or equal to a specified minimum.

maxlength

Checks that the number of characters in the field value is less than or equal to a specified maximum.

mask

Validates the field value using a regular expression to determine a match. If the value matches the regular expression, the field is valid.

byte

Checks that the field value is a valid byte value.

short

Checks that the field value is a valid short integer value.

integer

Checks that the field value is a valid integer value.

long

Checks that the field value is a valid long value.

float

Checks that the field value is a valid floating-point value.

double

Checks that the field value is a valid double value.

date

Checks that the field value matches a specified date format pattern (e.g., MM/dd/yyyy). The match can be strict or lenient; "strict" would require May 10, 1963 to be formatted (using the MM/dd/yyyy pattern) as 05/10/1963; "lenient" would allow 5/10/1963.

range

Checks that the field value is within a specified numeric range. This valdiator has been deprecated in favor of the type-specific range checks (intRange, floatRange, etc.).

intRange

Checks that the field value is within a range bounded by two int values.

floatRange

Checks that the field value is within a range bounded by two float values.

doubleRange

Checks that the field value is within a range bounded by two double values.

creditCard

Verifies that the format of the field value is valid for a credit card number. This validator is convenient to use instead of using mask.

email

Verifies that the format of the field value is valid for an electronic mail address (e.g., foo@bar.com). This validator is convenient to use instead of working with mask.

url

Verifies that the value entered is a valid uniform resource locator. Use this validator when you want to validate an input web location or hyperlink value.


The most up-to-date listing of the bundled validators can be found at http://struts.apache.org/userGuide/dev_validator.html#builtin.

Configuring the Validator

To use the Validator, first specify a plug-in element in your struts-config.xml file:

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">     <set-property property="pathnames"                      value="/WEB-INF/validator-rules.xml,                             /WEB-INF/validation.xml"/> </plug-in>

The pathnames property value specifies the Validator configuration files you're using. Typically, you specify one or more files here. The first file, validator-rules.xml, defines and declares the pluggable validators, listed in Table 8-1, which are bundled with the Struts distribution. The second file, validation.xml, declares how the validators are applied to your application.

You can specify more than these two files if needed.


A good approach is to have separate validation XML files for each major functional area of your application. For a large application, you might have a dozen of these files. The Validator supports multiple validation documents in the same manner that Struts supports struts-config documents (see Recipe 2.4).

To use the Validator with a hand-coded ActionForm, the ActionForm must extend org.apache.struts.action.ValidatorForm (or one of its subclasses). For a dynamic action form, the type must be org.apache.struts.action.DynaValidatorForm (or one of its subclasses). You specify how the validators apply to the form in the validation.xml file. Example 8-2 shows a portion of a validation.xml file that validates that the username and password are required on the form named MyLoginForm. This Validator form establishes minimum and maximum lengths for the password field.

Example 8.2. Validation for a login form
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE form-validation PUBLIC  "-//Apache Software Foundation//DTD Commons Validator Rules   Configuration 1.1//EN"  "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd"> <form-validation>     <formset>         <form name="MyLoginForm">             <field property="username"                     depends="required">                 <arg key="prompt.username"/>             </field>             <field property="password"                     depends="required, minlength,maxlength">                 <arg key="prompt.password"/>                 <arg key="${var:minlength}" name="minlength"                    resource="false"/>                 <arg key="${var:maxlength}" name="maxlength"                    resource="false"/>                 <var>                     <var-name>maxlength</var-name>                     <var-value>16</var-value>                 </var>                 <var>                     <var-name>minlength</var-name>                     <var-value>3</var-value>                 </var>             </field>         </form>     <formset> <form-validation>

The value of the name attribute specified in the form element is the name of the form from the form-bean element in the struts-config.xml file and not the type (class name) of the form.


You might think of a validation set as applying to all the fields of an ActionForm, and you can tie the validation set to an action path instead of the form name. This feature is referred to as action-based or path-based validation. The Validator applies this feature if the form subclasses ValidatorActionForm or DynaValidatorActionForm. When such a form is submitted to an Action, only the Validator form element, in which the name matches the path, applies, and only those fields specified in that validation set are checked. In this snippet from a validation.xml file, the username will be validated when the form is submitted to the action path /ProcessStep1:

<form name="/ProcessStep1">     <field property="username"             depends="required">         <arg key="prompt.username"/>     </field> </form> <form name="/ProcessStep2>     <field property="password"             depends="required">         <arg key="prompt.password"/>     </field> </form>

Validation is enabled for an action mapping by setting the action element's validate attribute to true. If validation fails, Struts forwards to the resource identified by the input attribute. The value of the input attribute represents the path to the resource, typically a JSP page, to forward control so the user can reinput data.

<action    path="/Login"            type="com.oreilly.strutsckbk.ch08.LoginAction"           scope="request"            name="MyLoginForm"         validate="true"           input="/login.jsp">     <forward name="success" path="/login_success.jsp"/> </action>

You can set the inputForward attribute to true on the controller element in a Struts configuration file so Struts will treat the value of the input attribute as the name of a local or global forward (see Recipe 7.4).


You're ready to apply validation across your application! Once you get in the groove of configuring validations and verifying that it all works as desired, you will be well on your way to creating a web application that will be robust enough to support the demands of those pesky creatures known as users.

Like most application features driven by XML configuration files, typographical mistakes may cause silent failures in your application that can be hard to diagnose and debug. If you find your application misbehaving after setting up the validations, you can turn off the validation by setting validate="false" in the action mapping. If everything works correctly down this "happy path," then you know that something is amiss with your validation setup.


See Also

For more of the basics on using the Validator, check out Programming Jakarta Struts by Chuck Cavaness (O'Reilly).



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

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