Commons Validator outside Struts framework
Introduction
Commons Validator API is a piece of software that let us to decouple the validation routines and the main code of the project. With Validator, we can save a lot of time using predefined rules to accomplish the repetive tasks. The constraints are defined in a xml document and can be reusable in several projects.
Maybe, you have already used Validator in Struts framework, but with minimal effort we can integrate in your application.
This is your actual application, you have validations written in java code in many parts, and the code is redundant, and not reusable. When you begin another project, you have to code again this validations or copy & paste. This way is a error prone aproach, and only recomended in very simple applications.

On the other side, we have Struts. This framework is modular, and one specific part has the only purpose of validation, commons validator. Despite validator was originally coded for struts is also valid for any other kind of applications.

Of course, this is not a real struts diagram, is only for this explanation purpose.
We want to plug validator inside the application and move the java code to xml document. In the future, adding more validation constraints will be quick and easy.

Requirements
The lastest version of validator is 1.3 and this are the dependences:
- commons-beanutils-1.7.0
- commons-collections-3.2
- commons-digester-1.7
- commons-logging-1.1
- commons-validator-1.3.0
- jakarta-oro-2.0.8
Validator parts
The validator integration process can be divided in several parts:
- rules/constraints definitions code: The code that makes the validations.
- rules/constraints definitions xml: A xml document with all the information of the above code.
- form definitions xml: The form and field constraints.
- validation code: The instantiation of Validator object and execution of validate method.
- parsing results: Getting the results of the process.
Configuration resources (.xml files and java code)
We must define the rules of validation like required, email or numeric. So, we need two resources, the java code, and the xml definition.
validation code
The java code, must be in a static method that returns boolean value. If returns true, the validation was succes and if returns false, the validation failed. We can use as many parameters as we need, but there is a minimum to work:
- object to validate, can be a form, a window or whatever you want
- Field object, to get field name and other data
This example reads the property of bean especified in field property,
then i used a method of GenericValidator:
- isBlankOrNull
- matchRegexp
- isByte
- isShort
- isInt
- isLong
- isFloat
- isDouble
- isDate
- isInRange
- isCreditCard
- isEmail
- isUrl
- maxLength
- minLength
- minValue
- maxValue
Validator provides a set of methods out-of-the-box to test the common validations.
validation rules xml
For each method coded we have to set an <validator> element inside <global> in the xml document.
<validator
name="integer"
classname="com.martincuervo.validator.SimpleValidator"
method="validateInteger"
methodParams="java.lang.Object,
org.apache.commons.validator.Field"
msg="error.integer"/>
- name: the unique name of the validation rule
- classname: the ful qualified name of the java class that contains the code
- method: the method name of the above class to execute when validator check this validation rule. Must be public, static and return boolean
- methodParams: List of full qualified name of the class used as parameters, must be separated with comas
- msg: resource bundle key to generate the user message
validation constraints
Now we have to apply the rule created to a field (or more…) of the form. In this example, the form is a simple bean, and the field is a simple attribute of this bean, in you application, the form can be a window, a collection, or something like that.
For each form we have to create a <form> element inside <formset>. In this <form> we can especify one or more <field> elements with one or more constraints.
<form name="person">
<field property="age" depends="integer">
<arg key="error.age" />
</field>
</form>
Is this piece of xml, i set integer constraint to age property the belongs to person form.
Validation code
The validation code is quite simple:
FileInputStream stream = new FileInputStream("NewFile.xml");
ValidatorResources config = new ValidatorResources(stream);
Validator v = new Validator(config, "person");
v.setParameter(Validator.BEAN_PARAM, person);
ValidatorResults r = v.validate();
First of all, we have to instantiate ValidatorResources with the stream or streams that contains the configuration xml. For learning pupouses i have merge the tipical config files into one. At this point you can isolate the validation rules in one file, and the constraint definitions into other.
Second step is Validator instance. In constructor you can set the form name, or later with setFormName(String) method. If you have to validate several forms, you don’t have to create new Validator instance for each form (if the resources are the same).
Next step is to assign the parameters. Those parameters were used in the rules code, and you can as many use as you want. First parameter of setParameter method is the class name, the full cualified name of the class used (you can use java.lang.Object or Validator.BEAN_PARAM), and the second is the object.
As you have seen, in the method validateInteger of SimpleValidator class, there is another param. Field, and the other validator clases are assigned automatically, so you can use ValidatorAction or Validation instance in your validation code.
And finally, the validation.
Parsing results
So, now the results of the validacion process. The above ValidatorResults instance contains the results. All the results, success and failed validations.
Iterator propertyNames = r.getPropertyNames().iterator();
while (propertyNames.hasNext()) {
String propertyName = (String) propertyNames.next();
ValidatorResult result = r.getValidatorResult(propertyName);
Iterator iter = result.getActions();
while(iter.hasNext()) {
String name = (String)iter.next();
ValidatorAction action = config.getValidatorAction(name);
System.out.println(propertyName + "." + name +
": " + result.isValid(name));
System.out.println(result.getField().getArg(0).getKey() +
", " + action.getMsg());
}
}
There are two nested loops, first loops over all properties, and second loops over all the validations of each property.
When you get the result, you can see if the validation was successfully and all other data like <arg> values.
Conclusion
Validator is a great software, you can connect it in you project and make all the validation in declarative manner, your code will be cleaner and more scalable. You can add more validation routines without affecting your actual logic or presentation, and the most important, can be reusable in other proyects.
I recomend you to try and use it.