Wednesday, 7 January 2009

In Need Of Validation - The 2005 Approach

Back in 2005, when we kicked off our project, we wanted to leverage the Commons Validator (at the time the most obvious choice for us) for validating form input.

For a typical form, such as validating a registration, this is pretty straightforward. On our site, we've minimalist, we only ask for a name and an email address, and we then send out a generated password that can be changed.

Hence, our login bean, SignUpCmd, has only two required fields: name and email.

The respective entry in validation.xml is not simple:


<form name="signUpCmd">
<field property="name" depends="required,minlength,maxlength,mask">
<msg name="required" key="forms.errors.requiredAndMinLength">
<msg name="mask" key="account.errors.nameSyntax">
<arg position="0" key="account.name.displayname">
<arg position="1" name="minlength" key="${var:minlength}" resource="false">
<arg position="1" name="required" key="${var:minlength}" resource="false">
<arg position="1" name="maxlength" key="${var:maxlength}" resource="false">
<var>
<var-name>minlength</var-name>
<var-value>${nameMinLength}</var-value>
</var>
<var>
<var-name>maxlength</var-name>
<var-value>${nameMaxLength}</var-value>
</var>
<var>
<var-name>mask</var-name>
<var-value>${screenNameMask}</var-value>
</var>
</field>
<field property="email" depends="required,maxlength,email">
<arg position="0" key="account.email.displayname">
<arg position="1" name="maxlength" key="${var:maxlength}" resource="false">
<var>
<var-name>maxlength</var-name>
<var-value>${emailMaxLength}</var-value>
</var>
</field>



Hmm... I can recall now why I was starting to wonder about the logic of this approach!

This was just the start. Most of our form editing and validation requirements involved flexible content, with the data entries stored in a map, named 'values'.

The result was that in order to extend our application, we had no need to change any Java code, we updated: our content definitions (e.g. adding a new enumerated attribute "Thoughts on the Matrix" to a dating profile with the options: "Not seen it", "If only they'd stopped at one", "Loved them all", "What's the Matrix?"), adding a single <wwm-form:enum> tag to the JSP for editing and displaying that content and, adding an entry into validation.xml.

And, it's at validation where we hit a critical problem: that Commons Validator references a map as values(viewsOnTheMatrix), but Spring's BeanWrapperImpl accesses maps (and arrays too) as values[viewsOnTheMatrix].

After some searching around, we found that it was a supposedly fixed bug: http://jira.springframework.org/browse/MOD-83, and on finding it wasn't, we found the only way forwards was to patch Spring ourselves to support the same approach as Commons Validator. Our patch is included in my comment in the above bug.

This has served us well for a number of years, with the caveat that each time we upgrade, we have to patch the source for spring-beans.jar.

Searching the forums, it's clear that we're not the only ones facing this difficulty with maps. The big issue for me, though is that with such a pluggable system, such as Spring, we should be able to get this sorted. There are a couple of approaches that I'm taking on this:
That task, though, will have to wait. I've got a birthday curry to go to!

No comments:

Post a Comment