ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Using the Validator Framework with Struts
Pages: 1, 2, 3

Hooking Up the Validator to Struts

Now that we've talked about the Validator, you should have a pretty good feel for it. Let's quickly talk about how easy it is to use the Validator framework with Struts.



The first thing you need to do is to make your Struts application aware of the Validator. You do this by using a new feature of Struts 1.1 called "Plug-in." Just add the following to the Struts configuration 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>

and Struts automatically becomes aware of the Validator.

The other necessary steps are to create the ActionForms (standard ones or Dynamic) and ensure the Validator configuration files are available, and away you go. There's no need to call the validation rules or do anything special. Struts will automatically do this, based on the declarative configurations. You will, however, need to have the error messages tag in the JSPs in order to see the validation failures.

Creating Your Own Validators

Even though the Validators provided by the framework cover many of the validation rules that Web applications require, there are special needs that will require you to create your own rules. Fortunately, the Validator framework is easily extensible and the effort to do so is minimal.

To create your own validator, just create a Java class that implements your special validation rule. For example, suppose you needed a rule to validate that a user was the legal drinking age; this might be necessary to purchase alcoholic beverages online. You could possibly use one of the existing validation rules, but it would be more obvious to create a rule to validate that the user meets the required drinking age. The Java class might look something like the one in Example 3.

Example 3. A custom validation rule

import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.util.StrutsValidatorUtil;

public class NewValidator implements Serializable{

  public static boolean validateDrinkingAge( Object bean,
    ValidatorAction va, 
    Field field, 
    ActionErrors errors, HttpServletRequest request) {

    String value = null;
    if (isString(bean)) {
      value = (String) bean;
    } else {
      value = 
        ValidatorUtil.getValueAsString(bean, field.getProperty());
    }
    String sMin = field.getVarValue("drinkingAge");

    if (!GenericValidator.isBlankOrNull(value)) {
      try {
        int iValue = Integer.parseInt(value);
        int drinkingAge = Integer.parseInt(sMin);

        if ( iValue < drinkingAge ){
          errors.add(field.getKey(),
          StrutsValidatorUtil.getActionError(request, va, field));
          return false;
        }
      } catch (Exception e) {
        errors.add(field.getKey(),
        StrutsValidatorUtil.getActionError(request, va, field));
        return false;
      }
    }
  return true;
}

private static boolean isString(Object o) {
  if (o == null) {
    return (true);
  }
  return (String.class.isInstance(o));
 }
}

After you create the new Validator, you simply add it to the list of existing Validators in the validation-rules.xml file. Once that's done, you can use the new Validator just like it was one of the "basic validators."

Using the Validator with a Non-Struts Application

As mentioned earlier, the Validator was originally designed for use with the Struts framework. However, because of its flexible design, there's no direct coupling to any Struts components, and you're free to use it in ordinary Java applications as well. There are, however, some steps that you'll have to take in order to make the Validator easier to digest.

You can utilize the same configuration files as in Web- based applications. This is another advantage of using the Validator framework. The Struts framework finds and loads these files based on the addition of the plug-in mentioned earlier. However, in non-Struts applications, the manner in which these configuration files are discovered and loaded must be done manually. This is typically done at application startup using the following method calls:

...
ValidatorResources resources = new ValidatorResources();

InputStream rules = 
   ValidateExample.class.getResourceAsStream("validator-rules.xml");

ValidatorResourcesInitializer.initialize(resources, in);

InputStream forms = 
   ValidateExample.class.getResourceAsStream("validation.xml");

ValidatorResourcesInitializer.initialize(resources, forms);

...

This snippet of code creates a new instance of a ValidatorResources class and initializes it based on the two Validator configuration files. The ValidatorResources object can then be used throughout your application to validate the configured JavaBeans.

Example 4 shows a small snippet of how you go about validating a Person bean using the initialized ValidatorResources object.

Example 4. A snippet of how to validate your beans using the Validator

// Suppose we already had a CheckoutForm object created and populated
CheckoutForm form = new CheckoutForm();

// Create a validator with the checkoutForm
Validator validator = new Validator(resources, "checkoutForm");

// Tell the validator which bean to validate against.  
validator.addResource(Validator.BEAN_KEY, form);

// Validate the checkoutForm object and store the validation results
ValidatorResults results = validator.validate();

In Example 4, you can see that the name of the JavaBean checkoutForm is being passed to the constructor of the Validator class. This is necessary so that the Validator instance knows which set of validation rules to use against the bean.

As you can see, using the Validator with non-Struts applications is a little less automatic, but still provides a more flexible solution. The other benefit is that it keeps the validation rules out of the source code and in external configuration files. This can save time when customization of your application is a vital aspect of your business.

Client-Side Versus Server-Side Validation

Finally, we should briefly mention the JavaScript support provided by the Validator. Because some applications would rather validate on the client side, it's necessary to sometimes write JavaScript to perform simple checks on the client. By client, we're referring to a Web browser.

The Validator provides the support for dynamically and automatically creating JavaScript validation rules based on rules within the configuration file. For each <validator> element, you can also include a <javascript> child element and include the JavaScript code right in the file. When a JSP is rendered that contains the appropriate custom tags, JavaScript will be rendered, as well, and perform validation on submittal of the form. The JSP custom tag is included in the set of Struts tags and is called JavaScriptValdiatorTag. The inclusion of the tag would look like:

<html:javascript formName="checkoutForm"/>

I think it's generally accepted that the amount of JavaScript should be limited when possible. However, when you need to perform some client-side validation, the Validator tags work very well and also support localization based on the user's locale.

Conclusion

By now, I hope I've enticed you to go and give the Validator framework a whirl. I've really only scratched the surface and there's much more available within the walls of the framework. The regular expression support alone could fill a small book.

Like any good framework, the Validator provides a solid foundation from which you can extend or customize the behavior to fit your specific needs. The overriding benefit of using a framework like the Validator is that it has already been built, has been tested by many, and is being actively and successfully used. Don't reinvent the wheel when you don't have to; save your energy for solving your core business problem, not one that is peripheral to your core business.


O'Reilly & Associates recently released (November 2002) Programming Jakarta Struts.

Chuck Cavaness is a graduate from Georgia Tech with degrees in computer engineering and computer science. He has built Java-based enterprise systems in the healthcare, banking, and B2B sectors. He is also the author of two O'Reilly books, Programming Jakarta Struts and Jakarta Struts Pocket Reference.


Return to ONJava.com.