OVal - Validate Your Models Quickly and Effortlessly!
Some time ago one of the projects at work required me to validate
some Java POJOs. Theses were my model classes and I’ve been creating
them from incoming WebService requests. One would say that XSD would be
sufficient for the task, for parts of this validations - sure, it would.
But there were some advanced rules XSD would not handle, or would render
the schema document very complicated.
Rules I needed to express were like:
person’s first_name and last_name should be of appropriate length -
between 2 and 20, and additionally one could pass a zero-length string
just to remove the previous value
state field should consist only defined values - as in
dictionary value - this one would be completable with XSD’s
enumerations, but would require often changing schema files and
redistributing them to interested parties :(
The library I’ve decided to use for this task is OVal and it came out really nice! Read on
to find out the details!
Oval is quite mature library that allows POJO validation, but is not
JSR303 (bean validation) implementation. It has converters that enable
it to understand those annotations, but I’m not sure about the
compatibility.
I’ve tried only a subset of the available checks, among which
were:
NotNull
NotEmpty
Length
There are many more, and their attributes give interesting ways to
configure the validation process. But using them was rather easy and did
not require to much brainstorming. What I really needed were custom
checks. And in this area OVal shows it’s strength. Implementing a check
is really easy.
I needed an annotation that would check a field against some values in
a dictionary. If field’s value was in the given set, than the validation
would succeed, if not, an exception would be thrown. To accomplish this
task it is required to implement two classes: annotation class and check
class - called by the validation engine on a given field.
Let’s start with our new annotation:
In the above snippet I’ve defined a check-annotation, that would be used like
this:
You can pass file - containing dictionary values for this field.
There is also message field in the annotation which is an error
message returned by the validation engine of failed check - pretty
handy. And can be expressed in .properties file as:
Placeholder, like context, will be replaced with correct values supplied by the
validation engine.
Annotating a field is not enough. It is also needed to create a validator
for this kind of check. The name of the class is already defined in
DictionaryValue annotation, it is called
DictionaryValueCheck and I’ve done this check this way:
What this basically does is:
when file is set - read dictionary content from the file into
map
upon check request just lookup value in dictionary parsed from the
input file
And that’s it!
For me Oval is really great tool. With it at ones disposal it is extremely easy to create any
imaginable validation you need. This library is really easy to use and
offers lots of handy features.
But perhaps I’m reinventing the wheel and all this can be done easily
with some other library? Share Your opinion!
Now that’s a great question. I’ve forgotten to write about this, but OVal offers profiles, which you can disable or enable whenever you like. You set a profile for a specific annotation. In your case let’s assume You have two operations: add and update. Your model has field annotated with @NotNull(profile="UPDATE"), which means we don’t want null values on it when updating. In _add_ operation you disable the profile called UPDATE, so the annotation is also disabled. When calling _update_ you enable the profile and the validation is performed.
More on this here: http://oval.sourceforge.net/userguide.html#d4e561
Question:
Say, we have an object with a primary key, that is mandatory (in the database), but described as AUTOINCREMENT. When client sends new object data, the primary key is obviously null, but we need to validate it for not-nullity in other cases.
Doea OVal handle variations / directions of validation?
Now that’s a great question. I’ve forgotten to write about this, but OVal offers profiles, which you can disable or enable whenever you like. You set a profile for a specific annotation. In your case let’s assume You have two operations: add and update. Your model has field annotated with @NotNull(profile="UPDATE"), which means we don’t want null values on it when updating. In _add_ operation you disable the profile called UPDATE, so the annotation is also disabled. When calling _update_ you enable the profile and the validation is performed.
More on this here: http://oval.sourceforge.net/userguide.html#d4e561
Question:
Say, we have an object with a primary key, that is mandatory (in the database), but described as AUTOINCREMENT. When client sends new object data, the primary key is obviously null, but we need to validate it for not-nullity in other cases.
Doea OVal handle variations / directions of validation?