Struts Tip #5 - Use Coarsed-Grained ActionForms

The biggest hassle for any Struts developer can maintaining the #@$!% ActionForms. The ActionForm provides several important services to an application, since it is

As a firewall it keeps untrusted input from passing directly into your application. As a field buffer, it stores new input so it can verified before it is passed to more trusting parts of your application, As a mutable transfer object (fka value object), the ActionForm provides an extensible container where data can collected and passed in a batch to one or more business or resource layer objects.

But, in practice, you usually need a different form-bean for each HTML form in your application. This makes it easy to store the data for each form under its own attribute, and to fine-tune the validation for each form.

Hey -- what's that about form-beans? I thought we were talking about ActionForms?

This is an important distinction. Each HTML form typically needs its own form-bean, but a form-bean is not an ActionForm. A form-bean identifies which ActionForm to use, in the same way an action-mapping identifies which Action class to use. Many Struts developers share Actions between action-mapping, but tend to forget that you can share ActionForms between form-beans too.

While ActionForms are vital objects, they are not subtle. Typically, they are a pure data-only JavaBean, with nothing but accessors and mutators. Occasionally, there is a helper method to transform data from one type to another, but even those are a simple wrappers around standard library functions. With the Struts-Validator, most ActionForms don't even need to subclass validate(). All that's needed is to define a formset for each form-bean, or attribute, that needs validation.

So, why bother with more than one ActionForm class? The form-bean determines the runtime attribute name, and therefore the formset the Struts-Validator will use. Neither the validator nor the autopopulation utilities care if there are more properties a form than are used with a given request. And, null properties consume fewer resources that instantiating yet another class. So why not just put all the application's properties together in a single ActionForm?

Worst case, you can define a base ActionForm with all the properties you need, and subclass to provide any custom validations. Meanwhile, by aggregating your application's properties into a single ActionForm, several key benefits are realized.

In a larger application being developed by a team, you may want more than one ActionForm for the application (even if you don't "need" one). There may, for example, be one ActionForm each each major segment of the application being handled by a smaller group or pair of programmers within the team. The important thing is to try and group together all the properties that will be used together, so that they are not continually re-defined throughout several related classes. ActionForms are objects too and can be subclassed like any other object.

So the next time you need an ActionForm to go with a new form-bean, think twice before creating a new class. Maybe you already have one you can reuse.

HTH, Ted.


Struts Tips are based on excerpts from the book Struts in Action. The tips released weekly on the MVC-Programmers List. To subscribe, visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in Action and Professional JSP Site Design. Ted also manages the JGuru Struts FAQ and moderates the Struts mailing list.

Copyright Ted Husted 2002. All rights reserved.