Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Ajax validation with Struts 2

Support for Ajax and JavaScript takes the pain out of Web-form validation

  • Print
  • Feedback

Page 3 of 6

Now it's time to introduce some custom validation into the form. The simplest XWork validator that comes with Struts 2 is the required validator. It only checks for null values and is often confused with requiredstring, which checks for empty strings and can be instructed to trim strings before the check. Since in the case of the example all three parameters are always present in the request, there is no need for the required validator, and I'll use requiredstring. I'll put it into the FirstAction-validation.xml file for the FirstAction, as shown in Listing 4:

Listing 4. Action validation configuration: requiredstring validator

 <validators>
   <validator type="requiredstring">
      <param name="fieldName">name</param>
      <message>Name is required</message>
   </validator>...

This results in a "Name is required" message appearing after form submission if nothing was entered in the name input field.

You can configure a field to have several validations applied. To make the configuration file more readable and maintainable, you can configure validators in two ways:

  • Field-wise: You nest <field-validator> entries in the <field> entry.
  • Validator-wise: You create a standalone <validator> entry. The standalone validator can either work on its own or be tied to a certain field with a <param name=fieldName> entry.

A name-validation configuration doing exactly the same job as Listing 4, but using field-wise validation, could look like Listing 5:

Listing 5. Action validation configuration: Field-wise validation

 <field name="name">
   <field-validator type="requiredstring">
      <param name="trim">true</param>
      <message>Name is required</message>
   </field-validator>
</field>...

To take advantage of multiple validators per one field, Listing 6 introduces a requirement for age to be a required field whose value must be between 21 and 122 inclusive:

Listing 6. Action validation configuration: Multiple validations per field

 <field name="age">
   <field-validator type="required">
      <message>Age is required</message>
   </field-validator>
   <field-validator type="int">
      <param name="min">21</param>
      <message>You must be an adult</message>
   </field-validator>
   <field-validator type="int">
      <param name="max">122</param>
      <message>The oldest human ever was 122 years old</message>
   </field-validator>
</field>...

The required validator in Listing 6 tries to receive a value from the object graph. This value will already be of the exact type defined in the action. That's why it is impossible to check simple Java types with the required validator. Even if field values are empty (null), they are cast to a corresponding value, 0 in case of int.

Validating dependent fields

The real power of the Struts 2 validation framework is unveiled when it comes to more-advanced validation use cases. In lots of situations a field value depends on another field value. For example, suppose you want a special age rule applied if name field's value is Joe. Struts 2 has a special validator capable of resolving Object Graph Navigation Language (OGNL) expressions. OGNL is a powerful expression language that lets you crawl Java object graphs. All Struts 2 action fields can be considered an object graph with action as a root. A special expression validator takes an OGNL expression as a parameter, evaluates it, and outputs an error message if the evaluated result is false. Listing 7 applies a rule for Joe to be no younger than 30:

Listing 7. Action validation configuration: Expression validation

 <validator type="expression">
   <param name="expression">!(name==Joe && age<30)</param>
   <message>Joe must be at least 30 yrs old</message>
</validator>

In this example, the expression validator is not tied to any field and will report an action error (which will be displayed by a <actionerror> Struts 2 custom tag). To tie expression validations to a field on the form, you should use a fieldexpression validator.

The most advanced validations are those involving business logic executed on the server side, most likely to access a data layer or legacy system. XWork provides several interfaces that can be implemented by custom validators. Instead of directly implementing all interfaces, your custom validator should extend the ValidatorSupport class, which implements all them for convenience. The validation logic should be placed in the overridden validate(object:Object) method.

For this article's example use case, the custom validator in Listing 8 checks Joe's gender and produces an error message if Joe claims to be a female. The validator method gets two values -- name and gender -- from the object graph. An error is added then if needed.

Listing 8. Custom validator

 public void validate(Object object) throws ValidationException {
   String name = (String)getFieldValue("name", object);
   Gender gender = (Gender)getFieldValue("gender", object);
   if("Joe".equals(name) && Gender.Female.equals(gender))
      addFieldError("gender", object);
}

  • Print
  • Feedback

Resources

More