Using Validator

 < Day Day Up > 



Using the Validator framework involves enabling the Validator plugin, configuring Validator's two configuration files, and creating Form Beans that extend Validator's ActionForm subclasses. The following sections explain how to configure and use the Validator in detail.

Enabling the Validator Plugin

Although the Validator framework comes packaged with Struts, by default Validator is not enabled. In order to enable and use Validator, you have to add to your application's struts-config.xml file the following definition for the plug-in tag:

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

This definition causes Struts to load and initialize the Validator plugin for your application. Upon initialization, the plugin loads the comma-delimited list of Validator configuration files specified by the pathnames property. Each configuration file's path should be specified using a Web application-relative path, as shown in the preceding example.

Note that your application's struts-config.xml file must conform to the Struts Configuration DTD, which specifies the order in which elements are to appear in the file. Because of this, you must place the Validator plug-in tag definition in the proper place in the file. The easiest way to ensure that you are properly ordering elements in the file is to use a tool like Struts Console that automatically formats your configuration file so that it conforms to the DTD.

Configuring validator-rules.xml

The Validator framework is set up as a pluggable system whereby each of its validation routines is simply a Java method that is plugged into the system to perform a specific validation. The validator-rules.xml file is used to declaratively plug in the validation routines that Validator will use for performing validations. Struts' example applications come packaged with preconfigured copies of this file. Under most circumstances, you will use these preconfigured copies and will not need to modify them unless you are adding your own custom validations to the framework.

Following is a sample validator-rules.xml file that illustrates how validation routines are plugged into Validator:

<!DOCTYPE form-validation PUBLIC           "-//Apache Software Foundation//DTD Commons            Validator Rules Configuration 1.0//EN"           "http://jakarta.apache.org/commons/dtds/validator_1_0.dtd"> <form-validation>   <global>     <validator name="required"           classname="org.apache.struts.validator.FieldChecks"              method="validateRequired"        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.required">       <javascript>         <![CDATA[         function validateRequired(form) {           var isValid = true;           var focusField = null;           var i = 0;           var fields = new Array();           oRequired = new required();           for (x in oRequired) {             var field = form[oRequired[x][0]];             if (field.type == 'text' ||                 field.type == 'textarea' ||                 field.type == 'file' ||                 field.type == 'select-one' ||                 field.type == 'radio' ||                 field.type == 'password') {               var value = '';               // get field's value               if (field.type == "select-one") {                 var si = field.selectedIndex;                 if (si >= 0) {                   value = field.options[si].value;                 }               } else {                 value = field.value;               }               if (trim(value).length == 0) {                 if (i == 0) {                   focusField = field;                 }                 fields[i++] = oRequired[x][1];                 isValid = false;               }             }           }           if (fields.length > 0) {             focusField.focus();             alert(fields.join('\n'));           }           return isValid;         }         // Trim whitespace from left and right sides of s.         function trim(s) {           return s.replace( /^\s*/, "" ).replace( /\s*$/, "" );         }         ]]>       </javascript>     </validator>   </global> </form-validation>

Each validation routine in the validator-rules.xml file has its own definition that is declared with a validator tag. The validator tag is used to assign a logical name to the routine, with the name attribute, and to specify the class and method for the routine. The logical name given to the routine will be used to refer to the routine by other routines in this file as well as by validation definitions in the validation.xml file.

Notice that the validator tag encapsulates a javascript tag. The javascript tag is used to define client-side JavaScript code for performing the same validation on the client side as is performed on the server side.

Included Validations

By default, Validator comes packaged with several basic validation routines that you can use to solve most validation scenarios. As mentioned, the sample applications provided by Struts come packaged with preconfigured validator-rules.xml files that define these routines. Table 6-1 lists each of the preconfigured validations by logical name and states its purpose.

Table 6-1: Validator's Preconfigured Validations

Validation

Description

byte

Validates that the specified field contains a valid byte.

creditCard

Validates that the specified field contains a valid credit card number.

date

Validates that the specified field contains a valid date.

double

Validates that the specified field contains a valid double.

email

Validates that the specified field contains a valid e-mail address.

float

Validates that the specified field contains a valid float.

floatRange

Validates that the specified field contains a valid float and falls within the specified range.

integer

Validates that the specified field contains a valid integer.

intRange

Validates that the specified field contains a valid integer and falls within the specified range.

long

Validates that the specified field contains a valid long.

mask

Validates that the specified field conforms to a given regular expression (or 'mask').

maxlength

Validates that the string in the specified field's length is less than or equal to the specified maximum length.

minlength

Validates that the string in the specified field's length is greater than or equal to the specified minimum length.

range

Deprecated
Use the intRange validation instead.

required

Validates that the specified field contains characters other than white space (i.e., space, tab, and newline characters).

requiredif

Performs the required validation on the specified field if a specified rule is met.

short

Validates that the specified field contains a valid short.

Note 

Detailed information on configuring the validator-rules.xml file is found in Chapter 18.

Creating Form Beans

In order to use Validator, your application's Form Beans have to subclass one of Validator's ActionForm subclasses instead of ActionForm itself. Validator's ActionForm subclasses provide an implementation for ActionForm's validate( ) method that hooks into the Validator framework. Instead of hard-coding validations into the validate( ) method, as you would normally do, you simply omit the method altogether because Validator provides the validation code for you.

Parallel to the core functionality provided by Struts, Validator gives you two paths to choose from when creating Form Beans. The first path you can choose is to create a concrete Form Bean object like the one shown here:

package com.jamesholmes.minihr; import org.apache.struts.validator.ValidatorForm; public class LogonForm extends ValidatorForm {   private String username;   private String password;      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;   } }

This class is similar to one that you would create if you were not using Validator; however, this class extends ValidatorForm instead of ActionForm. This class also does not provide an implementation for ActionForm's empty reset( ) and validate( ) methods, because ValidatorForm does.

You configure this Form Bean in the struts-config.xml file the same way you would a regular Form Bean, as shown here:

<form-beans>   <form-bean name="logonForm"              type="com.jamesholmes.minihr.LogonForm"/> </form-beans>

The logical name given to the Form Bean with the form-bean tag's name attribute is the name that you will use when defining validations in the validation.xml file, as shown here:

<!DOCTYPE form-validation PUBLIC           "-//Apache Software Foundation//DTD Commons            Validator Rules Configuration 1.0//EN"           "http://jakarta.apache.org/commons/dtds/validator_1_0.dtd"> <form-validation>   <formset>     <form name="logonForm">       <field property="username" depends="required">         <arg0 key="prompt.username"/>       </field>     </form>   </formset> </form-validation>

Validator uses the value of the form tag's name attribute to match validation definitions to the name of the Form Bean to which they are applied.

The second path you can choose when creating your Form Bean is to define a Dynamic Form Bean in the struts-config.xml file, as shown here:

<form-beans>   <form-bean name="logonForm"              type="org.apache.struts.validator.DynaValidatorForm">     <form-property name="username" type="java.lang.String"/>     <form-property name="password" type="java.lang.String"/>   </form-bean> </form-beans>

Dynamic Form Beans do not require you to create concrete Form Bean objects; instead, you define the properties that your Form Bean should have and their types, and Struts will dynamically create the Form Bean for you. Validator allows you to use this concept just as you would with core Struts. The only difference for Validator is that you specify that your Form Bean is of type org.apache.struts.validator.DynaValidatorForm instead of org.apache.struts.action.DynaActionForm.

Identical to the way concrete Form Beans work with Validator, the logical name given to Dynamic Form Beans is the name that you will use when defining validations in the validation.xml file. Validator uses the matching names to tie the validations to the Form Bean.

In addition to the two standard options for creating Form Beans, Validator provides an advanced feature for tying multiple validation definitions to one Form Bean definition. When using ValidatorForm- or DynaValidatorForm-based Form Beans, Validator uses the logical name for the Form Bean from the struts-config.xml file to map the Form Bean to validation definitions in the validation.xml file. This mechanism is ideal for most cases; however, there are scenarios where Form Beans are shared among multiple actions. One action may use all the Form Bean's fields and another action may use only a subset of the fields. Because validation definitions are tied to the Form Bean, the action that uses only a subset of the fields has no way of bypassing validations for the unused fields. When the Form Bean is validated, it will generate error messages for the unused fields because Validator has no way of knowing not to validate the unused fields; it simply sees them as missing or invalid.

To solve this problem, Validator provides two additional ActionForm subclasses that allow you to tie validations to actions instead of Form Beans. That way you can specify which validations to apply to the Form Bean based on which action is using the Form Bean. For concrete Form Beans, you subclass org.apache.struts.validator.ValidatorActionForm, as shown here:

public class AddressForm extends ValidatorActionForm {   … }

For Dynamic Form Beans, you specify a type of org.apache.struts.validator.DynaValidatorActionForm for your Form Bean definition in the struts-config.xml file:

<form-bean name="addressForm"            type="org.apache.struts.validator.DynaValidatorActionForm">   … </form-bean> 

Inside your validation.xml file, you map a set of validations to an action path instead of a Form Bean name, because if you have two actions defined, Create Address and Edit Address, which use the same Form Bean, as shown here, each has a unique action path:

<action-mappings>   <action path="/createAddress"           type="com.jamesholmes.minihr.CreateAddressAction"           name="addressForm"/>   <action path="/editAddress"           type="com.jamesholmes.minihr.EditAddressAction"           name="addressForm"/> </action-mappings>

The following validation.xml file snippet shows two sets of validations that are intended for the same Form Bean, but are distinguished by different action paths:

<formset>   <form name="/createAddress">     <field property="city" depends="required">       <arg0 key="prompt.city"/>     </field>   </form>   <form name="/editAddress">     <field property="state" depends="required">       <arg0 key="prompt.state"/>     </field>   </form> </formset>

Because your Form Bean subclasses either ValidatorActionForm or DynaValidatorActionForm, Validator knows to use an action path to find validations instead of the Form Bean's logical name.

Configuring validation.xml

The validation.xml file is used to declare sets of validations that should be applied to Form Beans. Each Form Bean that you want to validate has its own definition in this file. Inside that definition you specify the validations that you want to apply to the Form Bean's fields. Following is a sample validation.xml file that illustrates how validations are defined:

<!DOCTYPE form-validation PUBLIC           "-//Apache Software Foundation//DTD Commons            Validator Rules Configuration 1.0//EN"           "http://jakarta.apache.org/commons/dtds/validator_1_0.dtd"> <form-validation>   <formset>     <form name="logonForm">       <field property="username" depends="required">         <arg0 key="prompt.username"/>       </field>       <field property="password" depends="required">         <arg0 key="prompt.password"/>       </field>     </form>   </formset> </form-validation>

The first element in the validation.xml file is the <form-validation> element. This element is the master element for the file and is defined only once. Inside the <form-validation> element you define <form-set> elements that encapsulate multiple <form> elements. Generally, you will define only one <form-set> element in your file; however, you would use a separate one for each locale if you were internationalizing validations.

Each <form> element uses the name attribute to associate a name to the set of field validations it encompasses. Validator uses this logical name to map the validations to a Form Bean defined in the struts-config.xml file. Based on the type of Form Bean being validated, Validator will attempt to match the name either against a Form Bean's logical name or against an action's path. Inside the <form> element, <field> elements are used to define the validations that will be applied to specified Form Bean fields. The <field> element's property attribute corresponds to the name of a field in the specified Form Bean. The depends attribute specifies the logical names of validation routines from the validator-rules.xml file that should be applied to the field. The validations specified with the depends attribute will be performed in the order specified and they all must pass.

Note 

Detailed information on configuring the validation.xml file is found in Chapter 18.

Configuring ApplicationResources.properties

Validator uses Struts' Resource Bundle mechanism for externalizing error messages. Instead of having hard-coded error messages in the framework, Validator allows you to specify a key to a message in the ApplicationResources.properties file that is returned if a validation fails. Each validation routine in the validator-rules.xml file specifies an error message key with the validator tag's msg attribute, as shown here:

<validator name="required"       classname="org.apache.struts.validator.FieldChecks"          method="validateRequired"    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.required">

If the validation fails when it is run, the message corresponding to the key specified by the msg attribute will be returned.

The following snippet shows the default set of validation error messages from the ApplicationResources.properties file that comes prepackaged with Struts' example applications. Each message key corresponds to those specified by the validation routines in the validator-rules.xml file that also comes prepackaged with Struts' example applications:

# Error messages for Validator framework validations errors.required={0} is required. errors.minlength={0} cannot be less than {1} characters. errors.maxlength={0} cannot be greater than {2} characters. errors.invalid={0} is invalid. errors.byte={0} must be a byte. errors.short={0} must be a short. errors.integer={0} must be an integer. errors.long={0} must be a long. errors.float={0} must be a float. errors.double={0} must be a double. errors.date={0} is not a date. errors.range={0} is not in the range {1} through {2}. errors.creditcard={0} is not a valid credit card number. errors.email={0} is an invalid e-mail address.

Notice that each message has placeholders in the form of {0}, {1}, or {2}. At run time, the placeholders will be substituted for another value such as the name of the field being validated. This feature is especially useful in allowing you to create generic validation error messages that can be reused for several different fields of the same type.

Take for example the required validation's error message, errors.required:

errors.required={0} is required.

When you use the required validation in the validation.xml file, you have to define the value that should be used to substitute {0} in the error message:

<form name="auctionForm">   <field property="bid" depends="required">     <arg0 key="prompt.bid"/>   </field> </form> 

Error messages can have up to four placeholders: {0} - {3}. These placeholders are known as arg0 - arg3, respectively, and can be specified using the arg0 - arg3 tags. In the preceding example, the arg0 tag specifies the value that should be used to replace the {0} placeholder. This tag's key attribute specifies a message key from the ApplicationResources.properties file, such as the one shown next, whose value will be used as the replacement for the placeholder:

prompt.bid=Auction Bid

Using a message key for the placeholder value frees you from having to hard-code the replacement value over and over in the validation.xml file. However, if you don't want to use the Resource Bundle key/value mechanism to specify placeholder values, you can explicitly specify the placeholder value by using the following syntax for the arg0 tag:

<arg0 key="Auction Bid" resource="false"/>

In this example, the resource attribute is set to 'false', telling Validator that the value specified with the key attribute should be taken as the literal placeholder value and not as a key for a message in the ApplicationResources.properties file.

Note 

Detailed information on the ApplicationResources.properties file is found in Chapter 10.

Enabling Client-Side Validations

In addition to providing a framework for simplifying server-side form data validations, Validator provides an easy-to-use mechanism for performing client-side validations. Each validation routine defined in the validator-rules.xml file optionally specifies JavaScript code that can be run in the browser (client side) to perform the same validations that take place on the server side. When run on the client side, the validations will not allow the form to be submitted until they have all passed.

To enable client-side validation, you have to place the HTML Tag Library's javascript tag in each JSP for which you want validation performed, as shown here:

<html:javascript formName="logonForm"/>

The javascript tag requires that you use the formName attribute to specify the name of a <form> definition from the validation.xml file, as shown here, for which you want validations performed:

<form name="logonForm">   <field property="username" depends="required">     <arg0 key="prompt.username"/>   </field>   <field property="password" depends="required">     <arg0 key="prompt.password"/>   </field> </form>

All the validations that you have specified for the <form> definition to run on the server side will be run on the client side.



 < Day Day Up > 



Struts. The Complete Reference
Struts: The Complete Reference, 2nd Edition
ISBN: 0072263865
EAN: 2147483647
Year: 2003
Pages: 134
Authors: James Holmes

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