11.2 Installing and Configuring the Validator


The Validator framework is now part of the Jakarta Commons project. It's included with the Struts main distribution, but you can also get the latest version from the Commons download page at http://jakarta.apache.org/commons/. Unless you need the source code or the absolute latest version, you'll find all the necessary files included with the Struts 1.1 distribution.

11.2.1 Required Packages

The Validator depends on several other packages to function properly, and the most important of these is the Jakarta ORO package. The ORO package contains functionality for regular expressions, performing substitutions, and text splitting, among other utilities. The libraries were originally developed by ORO, Inc. and donated to the Apache Software Foundation. Earlier versions of the Validator framework depended on a different regular expression package, called Regexp, which is also a Jakarta project. However, ORO was considered the more complete of the two, and the Validator that is included with Struts 1.1 now depends on the ORO package.

Other packages required by the Validator are Commons BeansUtils, Commons Logging, Commons Collections, and Digester. All of the dependent packages for the Validator are included in the Struts 1.1 download. The commons-validator.jar and jakarta-oro.jar files need to be placed into the WEB-INF/lib directory for your web application. The other dependent JAR files must also be present, but they should already be there due to Struts framework requirements.

11.2.2 Configuring the Validation Rules

As mentioned earlier, the Validator framework allows the validation rules for an application to be declaratively configured. This means that they are specified externally to the application source. There are two important configuration files for the Validator framework: validation-rules.xml and validation.xml.

11.2.2.1 The validation-rules.xml file

The validation-rules.xml configuration file contains a global set of validation rules that can be used out of the box by your application. This file is application-neutral and can be used by any Struts application. You should need to modify this file only if you plan to modify or extend the default set of rules.

If you do need to extend the default rules, you might be better off putting your custom rules in a different XML file, so as to keep them separate from the default ones. This will help when it comes time to upgrade to a newer version of the Validator framework.


The validator-rules_1_1.dtd describes the syntax of the validation-rules.xml file. The root element is the form-validation element, which requires one or more global elements:

<!ELEMENT form-validation (global+)> <!ELEMENT global (validator+)>

Each validator element describes one unique validation rule. The following fragment from the validation-rules.xml file is the definition for the required validation rule:

<validator    name="required"   classname="org.apache.struts.util.StrutsValidator"   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"> </validator>

The validator element also allows a javascript subelement, but for the sake of brevity it is not shown here. The JavaScript support in the Validator framework is discussed later in the chapter.


The validator element supports seven attributes, as shown here:

<!ATTLIST validator name           CDATA #REQUIRED                     classname      CDATA #REQUIRED                     method         CDATA #REQUIRED                     methodParams   CDATA #REQUIRED                     msg            CDATA #REQUIRED                     depends        CDATA #IMPLIED                     jsFunctionName CDATA #IMPLIED>

The name attribute assigns a logical name to the validation rule. It is used to reference the rule from other rules within this file and from the application-specific validation file discussed in the next section. The name must be unique.

The classname and method attributes define the class and method that contain the logic for the validation rule. For example, as shown in the earlier code fragment, the validateRequired() method in the StrutsValidator class will be invoked for the required validation rule. The methodParams attribute is a comma-delimited list of parameters for the method defined in the method attribute.

The msg attribute is a key from the resource bundle. The Validator framework uses this value to look up a message from the Struts resource bundle when a validation error occurs. By default, the Validator framework uses the following values:

   errors.required={0} is required.    errors.minlength={0} cannot be less than {1} characters.    errors.maxlength={0} cannot be greater than {1} 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 email address

You should add these to your application's resource bundle, or change the key values in the validation-rules.xml file if you plan to use alternate messages.

The depends attribute is used to specify other validation rules that should be called before the rule specifying it. The depends attribute is illustrated in the minLength validation rule here:

<validator    name="minLength"   classname="org.apache.struts.util.StrutsValidator"   method="validateMinLength"   methodParams="java.lang.Object,     org.apache.commons.validator.ValidatorAction,     org.apache.commons.validator.Field,     org.apache.struts.action.ActionErrors,     javax.servlet.http.HttpServletRequest"   depends="required"   msg="errors.minlength"> </validator>

Before the minLength validation rule is called, the required rule will be invoked. You can also set up a rule to depend on multiple rules by separating the rules in the depends attribute with a comma:

depends="required,integer"

If a rule that is specified in the depends attribute fails validation, the next rule will not be called. For example, in the minLength validation rule shown previously, the validateMinLength() method will not be invoked if the required validation rule fails. This should stand to reason, because there's no sense in checking the length of a value if no value is present.

The final attribute supported by the validator element is the jsFunctionName attribute. This optional attribute allows you to specify the name of the JavaScript function. By default, the Validator action name is used.

The Validator framework is fairly generic. It contains very basic, atomic rules that can be used by any application. As you'll see later in this chapter, it's this generic quality that allows it to be used with non-Struts applications as well. The org. apache.commons.Validator.GenericValidator class implements the generic rules as a set of public static methods. Table 11-1 lists the set of validation rules available in the GenericValidator class.

Table 11-1. Validation rules in the GenericValidator class

Method name

Description

isBlankOrNull

Checks if the field isn't null and the length of the field is greater than zero, not including whitespace.

isByte

Checks if the value can safely be converted to a byte primitive.

isCreditCard

Checks if the field is a valid credit card number.

isDate

Checks if the field is a valid date.

isDouble

Checks if the value can safely be converted to a double primitive.

isEmail

Checks if the field is a valid email address.

isFloat

Checks if the value can safely be converted to a float primitive.

isInRange

Checks if the value is within a minimum and maximum range.

isInt

Checks if the value can safely be converted to an int primitive.

isLong

Checks if the value can safely be converted to a long primitive.

isShort

Checks if the value can safely be converted to a short primitive.

matchRegex p

Checks if the value matches the regular expression.

maxLength

Checks if the value's length is less than or equal to the maximum.

minLength

Checks if the value's length is greater than or equal to the minimum.


Because the validation rules in the GenericValidator are so fine-grained, the Struts developers added a utility class to the Struts framework called org.apache.struts.util.StrutsValidator, which defines a set of higher-level methods that are coupled to the Struts framework but make it easier to use the Validator with Struts. They are listed here without descriptions because the names are similar enough to the ones from Table 11-1 to indicate their functionality.

  • validateByte

  • validateCreditCard

  • validateDate

  • validateDouble

  • validateEmail

  • validateFloat

  • validateInteger

  • validateLong

  • validateMask

  • validateMinLength

  • validateMaxLength

  • validateRange

  • validateRequired

  • validateShort

The StrutsValidator class contains the concrete validation logic used by Struts. This class and the methods listed above are declaratively configured in the validation- rules.xml file. When one of these methods is invoked and the validation fails, an ActionError is automatically created and added to the ActionErrors object. These errors are stored in the request and made available to the view components.

11.2.3 The validation.xml file

The second configuration file that is required by the Validator framework is the validation.xml file. This file is application-specific; it describes which validation rules from the validation-rules.xml file are used by a particular ActionForm. This is what is meant by declaratively configured you don't have to put code inside of the ActionForm class. The validation logic is associated with one or more ActionForm classes through this external file.

The validation.xml file is governed by the validation_1_1.dtd. The outermost element is the form-validation element, which can contain two child elements, global and formset. The global element can be present zero or more times, while the formset element can be present one or more times:

<!ELEMENT form-validation (global*, formset+)>

The global element allows you to configure constant elements that can be used throughout the rest of the file:

<!ELEMENT global (constant*)>

This is analogous to how you might define a constant in a Java file and then use it throughout the class. The following fragment shows a global fragment that defines two constants:

<global>  <constant>   <constant-name>phone</constant-name>   <constant-value>^\(?(\d{3})\)?[-| ]?(\d{3})[-| ]?(\d{4})$</constant-value>  </constant>  <constant>   <constant-name>zip</constant-name>   <constant-value>^\d{5}(-\d{4})?$</constant-value>  </constant> </global>

This fragment includes two constants, phone and zip, although you can include as many as you need. These constants are available to the elements within the formset section. You can reuse them many times within the formset simply by referring to them by name.

This is best illustrated with an example. Example 11-1 shows a simple validation.xml file.

Example 11-1. A simple validation.xml file
<form-validation>  <global>   <constant>    <constant-name>phone</constant-name>    <constant-value>^\(?(\d{3})\)?[-| ]?(\d{3})[-| ]?(\d{4})$</constant-value>   </constant>                      </global>  <formset>      <form name="checkoutForm">    <field       property="phone"      depends="required,mask">      <arg0 key="registrationForm.firstname.displayname"/>      <var>        <var-name>mask</var-name>        <var-value>${phone}</var-value>      </var>          </field>        </form>               </formset>    </form-validation>

In Example 11-1, the phone constant that's declared in the global section is used in the var element to help validate the phone property.

The formset element can contain two child elements, constant and form. The constant element has the same format as the one in the global section. It can be present zero or more times. The form element can be present one or more times within the formset element:

<!ELEMENT formset (constant*, form+)>

The formset element supports two attributes that deal with I18N, language and country:

<!ATTLIST formset language CDATA #IMPLIED                   country  CDATA #IMPLIED>

If you don't have any I18N requirements for your validation routines and want to use the default locale, you can leave out these attributes. The Section 11.6 later in this chapter discusses this topic in more detail.

The form element defines a set of fields to be validated. The name corresponds to the identifier the application assigns to the form. In the case of the Struts framework, this is the name attribute from the form-beans section.

The form element defines a set of fields that are to be validated. It contains a single attribute name, which should match one of the name attributes from the form-beans section of the Struts configuration file.

The form element can contain one or more field elements:

<!ELEMENT form (field+)>

The field element corresponds to a specific property of a JavaBean that needs to be validated. In a Struts application, this JavaBean is an ActionForm. In Example 11-1, the sole field element for the checkoutForm corresponds to the phone property in an ActionForm called checkoutForm in the form-beans section of the Struts configuration file. The field element supports several attributes, which are listed in Table 11-2.

Table 11-2. The attributes of the field element

Attribute

Description

property

The property name of the JavaBean (or ActionForm) to be validated.

depends

The comma-delimited list of validation rules to apply against this field. For the field to succeed, all the validators must succeed.

page

The JavaBean corresponding to this form may include a page property. Only fields with a page attribute value that is equal to or less than the value of the page property on the form JavaBean are processed. This is useful when using a "wizard" approach to completing a large form, to ensure that a page is not skipped.

indexedListProperty

The method name that will return an array or a Collection used to retrieve the list and then loop through the list, performing the validations for this field.


Both the ValidatorActionForm and DynaValidatorActionForm match on the action mapping rather than the form name. That is, instead of matching on the form name in the name attribute of the form element, you can use the path attribute of the action element. This allows the same form to be used for different action mappings, where each action mapping may depend on only certain form fields to be validated and the others to be left alone.


The field element contains several child elements:

<!ELEMENT field (msg?, arg0?, arg1?, arg2?, arg3?, var*)>

The msg child element allows you to specify an alternate message for a field element. The validation rule can use this value instead of the default message declared with the rule. The value for the msg element must be a key from the application resource bundle. For example:

<field property="phone" depends="required,mask">   <msg name="mask" key="phone.invalidformat"/>   <arg0 key="registrationForm.firstname.displayname"/>   <var>     <var-name>mask</var-name>     <var-value>${phone}</var-value>   </var>                     </field>

The msg element supports three attributes:

<!ATTLIST msg name     CDATA #IMPLIED               key      CDATA #IMPLIED               resource CDATA #IMPLIED >

The name attribute specifies the rule with which the msg should be used. The value should be one of the rules specified in the validation-rules.xml file or in the global section.

The key attribute specifies a key from the resource bundle that should be added to the ActionError if validation fails. If you want to specify a literal message, rather than using the resource bundle, you can set the resource attribute to false. In this case, the key attribute is taken as a literal string.

The field element allows up to four additional elements to be included. These elements, named arg0, arg1, arg2, and arg3, are used to pass additional values to the message, either from the resource bundle or from the var or constant elements. The arg0 element defines the first replacement value, arg1 defines the second replacement value, and so on. Each arg element supports three attributes, name, key, and resource, which are the same as the attributes of the msg element described earlier.

Example 11-1 included elements for arg0 and arg1 like this:

<field property="phone" depends="required,mask,minLength">   <arg0 key="registrationForm.firstname.displayname"/>   <arg1 name="minlength" key="${var:minLength}" resource="false"/>   <var>    <var-name>mask</var-name>    <var-value>${phone}</var-value>   </var>        <var>    <var-name>minLength</var-name>    <var-value>5</var-value>   </var>                </field>

The last of the field child elements is the var element, as seen in Example 11-1 and in the previous fragment. The var element can set parameters that a field element may need to pass to one of its validation rules, such as the minimum and maximum values in a range validation. These parameters may also be referenced by one of the arg elements using a shell syntax: ${var:var-name}.

In Example 11-1, the substituted value for the phone constant is passed into the mask validation rule so that it can be used to check whether the property value conforms to the proper phone mask. The field element can have zero or more var elements.

Once you have the two XML resource files configured for your application, you need to place them in the WEB-INF directory. They will be referenced within the Struts configuration file, as described in the next section.

11.2.4 Plugging in the Validator

Each Struts application needs to know that the Validator framework is being employed. As discussed in Chapter 9, you can use the PlugIn mechanism to hook the Validator framework into a Struts application.

Earlier versions of the Validator used an extra servlet to inform the Struts application that the Validator components were present. The ValidatorServlet has been deprecated and should not be used.


The following fragment illustrates how to set up the Validator as a plug-in:

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

There was some confusion in one of the earlier beta releases for the Validator that used multiple set-property elements. That is no longer supported you should use a single set-property element that specifies multiple Validator resource files, separated by commas. Also notice that the property value is the plural pathnames.


The Struts framework will call the init() method in the ValidatorPlugIn class when the application starts up. During this method, the Validator resources from the XML files are loaded into memory so that they will be available to the application. Before calling the init( ) method, however, the pathnames property value is passed to the ValidatorPlugIn instance. This is how the ValidatorPlugIn finds out which Validator resources to load. For more information on how the PlugIn mechanism works, see Section 9.2.1.



Programming Jakarta Struts
Programming Jakarta Struts, 2nd Edition
ISBN: 0596006519
EAN: 2147483647
Year: 2003
Pages: 180

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