Struts DynaForms and Validators
15 Mar
Struts 1.1 (and probably even more so in 2.1) has a number of concepts that can be achieved in a number of ways. One of these that I have been exploring is form beans and form validation. Previously, on projects, I have done this by creating a class that extends ActionForm with a validate method. This has always led to:
a) Form classes that pretty much mirror persistence objects
b) Methods that populate to / from persistence objects (even if mostly done using the commons collection to do BeanUtils.copyProperties)
c) Presentation / business logic that didn’t belong in a form
d) Complex inheritance hierarchies to avoid duplication.
The alternative is to use DynaForms and Validators. Both of these concepts are fairly well documented in isolation, but I found scant documentation on using them together.
DynaForms are basically dynamically created forms driven by form-beans specified in struts-config.xml. They may either be of type DynaForm, or DynaValidatorForm – for use with Validators.
A form bean in struts-config looks something like:
<form-bean
name="mailForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="pop3Host" type="java.lang.String"/>
<form-property name="pop3Port" type="java.lang.Integer"/>
<form-property name="from" type="java.lang.String"/>
...
</form-bean>
To allow the use of Validators, first a plug-in needs to be created in struts-config.xml:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validation.xml,
/WEB-INF/validator-rules.xml"/>
</plug-in>
validation.xml comes with the struts distribution and needs to be included in the WEB-INF directory of the deployed WAR. validator-rules.xml is where you specify the validation rules for each form property (der!). Validators may be specified for a form bean, in which case the validation will be called for every instance of that form bean, or for an action path (e.g. /SendEmail). Struts comes with a bunch of standard validation rules that cover probably 90% of what projects would need, but it also allows for easy creation of custom rules.
A validation rule, using only out-of-box validations, may look like:
<form-validation>
<formset>
<form name="/SubmitDetails">
<field property="from"
depends="required,email">
<arg0 key="mailForm.from"/>
</field>
<field property="pop3Host"
depends="required">
<arg0 key="mailForm.pop3Host"/>
</field>
<field property="pop3Port"
depends="required,integer">
<arg0 key="mailForm.pop3Port"/>
</field>
....
</form>
</formset>
</form-validation>
I like the fact that there is a validation rule for email addresses. So now all that’s left to do is use the bean. This is achieved thus:
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm,
HttpServletRequest request, HttpServletResponse response) throws Exception {
DynaActionForm formBean = (DynaActionForm) actionForm;
String pop3host = (String) formBean.get("pop3Host");
Integer pop3port = (Integer) formBean.get("pop3Port");
String from = (String) formBean.get("from");
...
}
And the JSP has no idea that it’s referencing a DynaForm instead of an ActionForm so there are no changes there…
Now that’s pretty cool. No redundant code. Clear separation of responsibilities. No violation of the DRY principle. Using code generation. Getting maximum return for minimum effort.





Well, given that the form properties are stored in a map of some sort I don’t think it will because BeanUtils.copyProperties uses reflection to find the properties. However, maybe there’s another util that has smarts in it to use a map rather than reflection… This might be what you’re looking for but I haven’t tried it out: http://jakarta.apache.org/commons/beanutils/commons-beanutils-1.7.0/docs/api/
Hi, What about the use of BeanUtils.copyProperties, do I can use it with DynaForms? I’m not shur of this… else… there is other option? Thks.
Speak for yourself, Mr Suse
You are such a geek
I guess whether or not you would use it would depend on the size of the project. If you have a large volume of forms with validation it would make reading and maintaining the struts-config a nightmare. Custom validations are written in Java, they’re just hooked up to the form through the XML so you can easily write unit tests for them.
Hi Pam,
I have to admit, Im not a big fan of either DynaForms or the Struts Validator…
Basically I dislike “code in XML” instead of Java – Its harder to read than well written java code, harder to debug, and out of reach of my beloved refactoring tools.
And what does it get me? For complex validations its usually actually simpler and more intuitive to implement them in Java – the out of the box validations are nice but I would rather access them as a set of standard java libraries…