|
From: Daniel M. <mi...@pa...> - 2004-03-01 02:31:21
|
Hello everyone,
I have recently been working on a commons-validator extension/addition to
the Spring framework. My current implementation consists of a
org.springframework.validation.commons package with about six classes. It
provides an implementation of the org.springframework.validation.Validator
interface that would encapsulate the functionality of the commons validator.
A user's project could simply add the necessary commons-validator config
files (validator-rules.xml, validation.xml), jars (commons-validator.jar),
and wire up a few beans and have completely xml configured validation.
By the way, my implementation for Spring will be much handier than the
Struts validator: it will allow easy extension of the validator. A user
could simply wire up a custom validator with my Spring-commons-validator
object. The commons-validator could easily be invoked by the custom
validator. For instance, this provides a logical way for users to implement
complex validation routines in a custom validator and leave the boring stuff
to the commons-validator (required, int, date, etc). To get back to the
point, the only way to extend the validator in Struts is to (1) either code
pluggable validators for the commons validator or (2) add a validate()
method to your ActionForm that does the complex stuff. I don't like the
first approach because it's cumbersome and one must understand the innards
of the commons-validator to do it. The second approach usually ends up
adding unnecessary complexity to a form. Furthermore, if you're using
DynaValidatorForms you have to extend the DynaValidatorForm class to add
this functionality, which (imo) puts validation logic in a not-so-logical
location.
Now this may all be sounding fine and dandy, and you're all saying "OK.
Let's have a look at the code so we can see if we'd like to use it." or even
better "Hey, give us your code...we really need that." But there's a
catch...
Background Info
The commons-validator uses message resources to identify arguments (such as
field names) for validation messages. For example, the base message would be
error.required="{0} is required." and arg0="formName.fieldName.label" (or
any other message resource identifier). Upon validation failure, the
validator resolves this message resource identifier to its corresponding
message in order to add it to the arguments array for the Errors object
(ActionErrors in Struts). The Struts validator adds a request object to the
commons-validator's map of resources, so request attributes may be used in
validation methods. Hence, the validator has a way to access the locale of
the current request as well as message resources to resolve message resource
identifiers. Currently, the Validator interface in Spring only specifies the
command object and the errors object as arguments, so I have no way of
getting these resources.
Ideally, the validator should not have to worry about resolving message
resources--it should only do validation. However, the commons-validator not
only does this, but also provides for locale-specific validation
configurations, so it seems necessary to have such information.
I have come up with two possible solutions for this problem.
(1) Add another method to the Spring Validator interface with something like
the following method signature:
public void validate(javax.servlet.http.HttpServletRequest request,
java.lang.Object obj, Errors errors)
I don't like this because it depends on a web context. One of the things I
was hoping for was the ability to use the commons-validator to validate
business objects in the middle tier, instead of only for the web. Of course,
the new method could simply provide the Locale and MessageResources, which
would possibly solve that problem.
(2) Improve the handling of Errors objects to allow message resources to be
specified as arguments that would not be resolved to their corresponding
messages until reaching the view. I really like this solution, but I have
not thought it through completely. One more note: since the errorArgs
parameter is an array of Objects (not an array of Strings), maybe there
would be a way to use a "Message" object that would be resolved at a later
time, while preserving the current functionality of Strings that are used
directly as arguments. For all I know, there is already a way to do this (it
seems logical enough), and I just don't know about it. This J2EE stuff is so
hard to keep up with...
Please provide response, and I will attempt to accommodate (or at least
consider) any wishes that may be expressed pertaining to additional features
or other adjustments. One area that I know should be supported, but I have
not worked on yet is the WizardController (multiple pages/stages of
validation per bean/form). I believe the commons-validator already supports
this, so it should only be a matter of adding another class or so to my
package to allow such functionality.
Thank you,
Daniel Miller
P.S. Sorry for being so long winded. I'll shut up now until I hear back from
you. :)
|