The first part of this series introduced MyFaces ExtVal. We
saw that MyFaces ExtVal allows client-side as well as server-side validation,
based on validation constraints as well as information provided by JPA
annotations. In this part, you’ll learn how to replace standard JSF validators
with annotations, and the usage of other MyFaces ExtVal annotations that allow you
to validate values across input components. MyFaces ExtVal offers these and
other functionalities out-of-the-box, and it’s also possible to provide add-ons
for MyFaces ExtVal. We’ll look at one add-on that allows you to bypass
Annotations instead of JSF-Validator-Tags
The examples included in every MyFaces ExtVal release (see binaries and source distributions) as
well as the examples at os890
(a Google Code project for open source case and feasibility studies as well as
short examples) are a useful reference for learning how to use MyFaces ExtVal.
Let’s take a look at the MyFaces ExtVal annotations that replace the standard
validator tags of JSF.
The following table shows the standard tags and their
a type-safe replacement for the standard tag. Instead of the validatorId, you
reference the validator class directly. The other annotations just delegate to
the default implementations of the equivalent standard JSF validators. If you
have registered a custom validator implementation to replace the standard JSF
validator, this custom validator is automatically used by MyFaces ExtVal.
Beside these replacements MyFaces ExtVal offers other annotations
you can use out of the box. You can find a complete list here.
It’s also quite easy to validate custom annotations.
If you look at JSF 1.x validations, you will see that the required attribute of input components
is a special case in JSF. In comparison to other currently available validation
frameworks for JSF 1.x, MyFaces ExtVal provides @Required
as a full replacement for the required
attribute (and of course it has some other great features). Furthermore, there
are implicit required validations. Figure 1 shows the example from part 1
including the usage of @Length.
Figure 1 shows a simple entity including MyFaces ExtVal annotations
If the minimum
attribute of @Length is greater
than 0 (the default value), the field is automatically required. Since other
JSF 1.x validation frameworks still need the required
attribute, they don’t support that (due to the behavior of the standard
required validation mechanism). The same applies for @Column(nullable =false), which leads to a required field
as well. Also the validation error messages of the standard validators are reused
by the default validation strategies of MyFaces ExtVal, so there isn’t a
special attribute for a validation error message key. That also means that these
validation strategies don’t use the message resolver mechanism of MyFaces
ExtVal. If you would like to use message resolving for annotations that
replaces the standard JSF validator message resolving mechanism, such as when you
have to load messages from an alternative message source like a database, you
have to implement custom annotations (which is pretty easy).
Hint: You don’t have to use JPA annotations (the support
MyFaces ExtVal provides replacements to express the same constraints without
JPA annotations. If you don’t like to use the annotations of a JSF centric
validation framework within your entities, it’s possible to provide custom
annotations. Furthermore, there will be an additional add-on in the os890
project for the next version of MyFaces ExtVal that allows you to provide
metadata separately (if the architecture of your application requires such a
separation). Since MyFaces ExtVal doesn’t introduce special requirements to
annotations, you are free to design them as you prefer. The MyFaces ExtVal
documentation and os890
examples show how to implement such custom constraints. In the next part of
this article series, we will take a closer look at custom annotations.
Validation without blinders
Standard JSF validation is restricted to input fields. In
some cases you need to validate values across different fields. With MyFaces
ExtVal, you can easily specify such cross-validations during the validation
phase of JSF, saving you a lot of time and effort. Figure 2 shows a very simple
case of cross-validation based on the previous example.
Figure 2 Added cross-validation constraint with simple syntax
leads to cross-validation. In this case the first and last names cannot be
equal. If a form contains input components which reference both properties (the
annotated one and the referenced one), the converted values are used for
validation. The minimum requirement for cross-validation is that the property that
hosts the cross-validation annotation is bound to an input component of the
current form. If the lastName property
of the previous example isn’t referenced by an input component of the current
form, the model value is used for validation instead. (If you would like to
provide a different validation error message in case of such a model-aware
cross-validation, it’s possible to provide a so called reverse-violation-message.)
Besides this simple syntax for referencing the target
property, you can also use valid EL expressions, as well as local property-chains.
This and other concepts are described in the following example:
Figure 3 Usage of MyFaces ExtVal annotations
Figure 3 shows a backing bean that is used to change a
password. That means the user has to enter the old password, which has to be
equal to the password stored in the model. In this case an EL expression is
used to reference the password property
of the person who is referenced in the same class. The oldPassword property hosts @Required.
Since the password property of the Person
class is required as well, in this scenario this would also be checked implicitly
due to @Equals. In this case @Required (and not @Equals) is used to display a required
marker, if the used component supports this feature. Furthermore, in this
example @NotEquals indicates
that the old password has to differ from the new password.
The second property in Figure 3 is the password property. In this case @Equals ensures that the new password
is equivalent to the repeated password. Moreover, the property hosts @JoinValidation, which means that all
constraints at the referenced target (it’s registrationPage.person.password)
are also used for the property hosting the annotation (the registrationPage.password property).
In this special scenario you need to use a different password property. If you
would bind the password input field directly to the password property of the Person class (registrationPage.person.password), the value of the old
password (in this case the obfuscated value) would be displayed instead of an
empty input field. In this case you have to provide an additional property to
store the password (registrationPage.password).
If validation is successful, you can start to process the valid password. As
you can see in Figure 3, the final implementation of the action-method is
straightforward and you don’t have to worry about cross-validation logic at
property illustrates how to provide a custom validation error message via
annotations that support the message resolver mechanism. Further details about
this mechanism are available at the MyFaces ExtVal Wiki as well as os890.
The implementation of the finish
method is quite simple. All validations are performed in the Process
Validations phase of JSF. So all constraints have to be valid before the action
method gets executed. That’s the reason why you can simply replace the old
password of the model with the new password that is stored in the page bean.
As you see in the fragment in figure 4, there is no
validation logic required within the page (as always with MyFaces ExtVal).
Figure 4 The page fragment
Figure 5 shows the rendered page after the user tried to enter
a wrong value for the old password.
Figure 5 The rendered page after cross-validation violation
Sometimes you have to skip validation. In the previous example
we have to enter the old password. Let’s assume (just as a simple example) that
if a user doesn’t remember the old password, an administrator has to reset this
password. You could do that with the same functionality if you add @SkipValidation.
With this annotation all constraints below @SkipValidation are skipped. They are
only skipped if at least one of the provided conditions returns true and if the validation strategies
for these annotations host @SkipValidationSupport.
validation strategies doesn’t affect your constraints—it’s possible to register
a custom validation strategy which changes this support for an existing
constraint. That means that, for instance, validations based on JPA annotations
won’t be skipped.
Normally it doesn’t make sense to skip validation for
constraints that are defined at the persistence layer. If you do, you won’t be
able to save these entities in case of a violation. (While it’s not common, there
are special use cases that require you to save an intermediate result temporarily
so you can later on persist the final state.) If you would like to change that
for the whole application, you can register your custom validation strategy that
hosts @SkipValidationSupport (or
not). This annotation is included in the property-validation module of MyFaces
ExtVal. In the next section you will see a more fine-grained mechanism
(provided by an add-on) which allows you to bypass this. The usage of @SkipValidation is illustrated in figure
Figure 6 Conditional validation
All constraints you see in this example can be skipped.
Every constraint you don’t want to skip has to be placed before @SkipValidation. If you already have
information in place which provides the same information as @SkipValidationSupport, MyFaces ExtVal
(1.x.2+) provides a new mechanism to reuse this information. As you can see in
slides of the MyFaces ExtVal 1.x2 release, it’s possible to define custom
markers for your validation strategy, or you can register the validation
If you would like to use a more fine grained approach like @MyRequired in figure 7, you have to
implement it on your own. However, it isn’t that difficult – I’ll show how to
write custom constraints in the next article. Further constraints and add-ons to
allow a more fine-grained usage are hosted at os890.
Figure 7 Custom annotations with fine grained conditions
Sometimes it’s necessary to bypass all constraints for a
special page, or if the user clicks on a special command component. Therefore,
project offers a bypass-validation add-on for MyFaces ExtVal.
Figure 8 shows three action methods with different usages of
the bypass-validation add-on. The first action method hosts @BypassValidation. That means a
command component bound to this method bypasses all skippable constraints. If
you really have to skip all constraints regardless of @SkipValidationSupport, you have to set the all attribute of @BypassValidation to true. You can see an example in the
second action method. The last action method of the following example shows a
conditional bypass. If at least one of the provided conditions returns true,
the bypass validation mechanism is triggered.
Figure 8 @BypassValidation for action methods
Beside bypassing via action methods, the add-on also offers
an annotation which offers a concept similar to view-controller annotations in
MyFaces Orchestra and Apache Shale. Figure 9 shows two example usages.
Figure 9 Two example usages of @BypassValidationController
The first usage of @BypassValidationController
means that all skippable constraints are skipped if the value expression uses
the registration-page-bean. The second usage means that all constraints are
skipped for the /pages/registration.xhtml
view-id, if the value expression references the Person object and at least one
condition returns true.
This second part of the MyFaces ExtVal article series shows
the easy usage of simple MyFaces ExtVal constraints as well as annotation-based
cross-validation. It explains how to skip validation via out-of-the-box
mechanisms as well as an alternative approach which is available via a MyFaces
ExtVal add-on. This add-on offers an annotation for action methods and one that
supports a concept similar to the annotation based view-controller approach. In
the next part I'll explain how you can implement custom annotations as well as
client-side validation based on annotations.