Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
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
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:
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-validator> entries in the <field> entry.
<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:
<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:
<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.
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:
<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.
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);
}
More