|
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.
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.
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 validationpackage 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 .
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 ValidatorTo 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.
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>
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'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.
See AlsoFor more of the basics on using the Validator, check out Programming Jakarta Struts by Chuck Cavaness (O'Reilly). |
|