Apache MyFaces Extensions Validator

Exclusive offer: get 50% off this eBook here
Apache MyFaces 1.2 Web Application Development

Apache MyFaces 1.2 Web Application Development — Save 50%

Building next-generation web applications with JSF and Facelets

$26.99    $13.50
by Bart Kummel | March 2010 | Java Open Source Web Development

In this article by Bart Kummel, author of Apache MyFaces 1.2 Web Application Development, you will be able to:  

  • Set up a project to use ExtVal
  • Use ExtVal to generate validation based on JPA annotations
  • Use ExtVal’s added annotations for additional validation
  • Implement cross validation using ExtVal’s annotations
  • Use ExtVal with custom JSF validators
  • Create custom error messages for ExtVal validations
  • Override and extend ExtVal’s default behavior

Setting up ExtVal

As with all other libraries, we start by downloading ExtVal and installing it in our project. As with many other JSF libraries, the ExtVal project has different branches for JSF 1.1 and 1.2. The first two digits of ExtVal’s version number are the JSF version they are made for. So ExtVal 1.1.x is the xth version of ExtVal for JSF 1.1, whereas ExtVal 1.2.x is the xth version for JSF 1.2. Versions of ExtVal are not released very often. At the time of writing this article, only two official releases have been published for each branch. According to the lead developer of ExtVal, a third release (1.1.3 and 1.2.3) is in the works for both branches, as well as a first release from the new JSF 2.0 branch.

Apart from stable releases, ExtVal offers snapshot builds that are created on a regular basis. The snapshots are created manually, which gives some guarantees about the quality compared to automatically-created daily releases. No snapshots with major bugs will be created. According to the lead developer of ExtVal, the snapshot builds have “milestone quality”.

Because of some issues and limitations in ExtVal 1.2.2, a snapshot build of ExtVal 1.2.3 was used while writing this article. A stable release of ExtVal 1.2.3 is expected to be available soon after the publishing date of this article. Stable releases can be downloaded from the ExtVal download site at http://myfaces.apache.org/extensions/validator/download.html. The downloaded ZIP file will contain all of the ExtVal modules, as listed in the next table. Note that more modules may be added to ExtVal in future releases. It is also possible that additional support modules will be provided by others. For example, a JSF component project may create a support module to get the most out of its components with ExtVal.

Regarding component support modules, it is also worth mentioning the “Sandbox 890” project, which provides proof of concept implementations of support modules for some non-MyFaces component libraries. Currently, proofs of concept are available for IceFaces, PrimeFaces, RichFaces, and OpenFaces. The source code for the proofs of concept can be found at http://myfaces.apache.org/extensions/validator/download.html. Ready-to-use JARs can be downloaded from http://code.google.com/p/os890-m2-repository/source/browse/#svn/trunk/sandbox890/sandbox890/extensions/validator/component-support-modules.

Library

Description

myfaces-extval-core-1.2.x.jar

The core of ExtVal. This library should be added to the project in all cases.

myfaces-extval-property-validation-1.2.x.jar

Extension module that adds several custom ExtVal annotations that we can use in our Model layer.

myfaces-extval-generic-support-1.2.x.jar

Extension module for generic JSF component support. This library should be added to the project in almost all cases. There are two cases when we don't need this generic support library, which are as follows:

  • If we're using a support library for a specific component library, such as the Trinidad support module mentioned in the following row in this table
  • If the component library we're using is 100% compliant with the JSF specification, which is almost never the case

If no specific support module is in use, and it is unclear if the generic module is needed, it is safe to add it anyway. It is also a good idea to take a look at the Tested Compatibility section on the ExtVal wiki at http://wiki.apache.org/myfaces/Extensions/Validator/.

myfaces-extval-trinidad-support-1.2.x.jar

Extension module that supports the MyFaces Trinidad JSF components. If we use this one, we don't need the "generic support" module. The Trinidad support module will make use of Trinidad's client-side validation options where possible. So we get client-side validation based on annotations in our Model with no extra effort.

myfaces-extval-bean-validation-1.2.x.jar

Extension module that adds support for Bean Validation (JSR 303) annotations. This module will be available from the third release of ExtVal (*.*.3).

Snapshot builds of ExtVal can be downloaded from ExtVal’s Maven snapshot repository, which can be found at http://people.apache.org/maven-snapshot-repository/org/apache/myfaces/extensions/validator/. In the case of snapshot builds, no single ZIP file is available, and each module has to be downloaded separately as a JAR file. Note that if Maven is used, there is no need to manually download the snapshots. In that case, we only have to change the version number in the pom.xml file to a snapshot version number, and Maven will automatically download the latest snapshot. The following table lists the URLs within the Maven repository from where the modules can be downloaded:

Module

URL

Core

myfaces-extval-core/

Property validation

validation-modules/myfaces-extval-property-validation/

Generic support

component-support-modules/myfaces-extval-generic-support/

Trinidad support

component-support-modules/myfaces-extval-trinidad-support/

Bean validation (JSR 303)

validation-modules/myfaces-extval-bean-validation/

URLs in this table are relative to the URL of the Maven repository that we just saw. After each URL, 1.2.x-SNAPSHOT/ has to be appended, where 1.2.x has to be replaced by the appropriate version number.

Once we’ve finished downloading, we can start adding the JARs to our project. ExtVal differs in one thing from other libraries—it needs to access our Model and View project. So we have to add the ExtVal libraries to the lib directory of the EAR, instead of the WAR or the JAR with the entities. Some libraries that ExtVal uses have to be moved there as well. If we don’t do this, we’ll end up with all sorts of weird exceptions related to class-loading errors.

Libraries that are added to the lib directory of an EAR are automatically available to all contained WAR and JAR files. However, depending on the IDE and build system that we are using, we may have to take some additional steps to be able to build the WAR and JAR with dependencies to the libraries in the EAR’s lib directory.

Apache MyFaces 1.2 Web Application Development

This image shows a simplified structure of the EAR with ExtVal’s libraries added to it. Note that the MyFaces ExtVal and dependencies node in the image actually represents multiple JAR files. It is important to verify that none of the libraries that are in the lib directory of the EAR are included in either the WAR or the entities JAR. Otherwise, we could still encounter class-loading conflicts. The following table lists all of the libraries that have to be moved into the EAR to avoid these class-loading conflicts:

Library

Explanation

myfaces-extval-*.jar

Of course, all of the needed ExtVal JARs should be in the EAR.

asm-1.5.x.jar, cglib-2.x_y.jar

These are libraries that ExtVal depends on. They are bundled with the ExtVal download. They're not bundled with snapshot releases.

jsf-facelets.jar

We're using Facelets, so ExtVal has to use it to add validations within our Facelets pages. So if we didn't use Facelets, this one would not be needed.

myfaces-api-1.2.*, myfaces-impl-1.2.*

We're using MyFaces Core as JSF implementation. ExtVal will need those libs too. Note that if we use the application server's default JSF implementation, we don't have to add these either to the EAR or to the WAR.

trinidad-api-1.2.*, trinidad-impl-1.2.*

We're using Trinidad, and ExtVal offers some Trinidad-specific features through the "Trinidad support" extension. In that case, the Trinidad libraries should be in the EAR too.

commons-*.jar

Various libraries that we just mentioned depend on one or more libraries from the Apache Commons project. They should also be moved to the EAR file to be sure that no class-loading errors occur.

Note that the aforementioned changes in our project structure are necessary only because we chose to have our Model layer in a separate JAR file. In smaller projects, it is often the case that the whole project is deployed as a single WAR file without enclosing it in an EAR. If we had chosen that strategy, no changes to the structure would have been necessary and we could have added all of the libraries to the WAR file, as we would do with any other library.

Other than including the necessary libraries as discussed before, no configuration is needed to get started with ExtVal. ExtVal uses the convention over configuration pattern extensively. That means, a lot of sensible defaults are chosen, and as long as we’re satisfied with the defaults, no configuration is needed. The next section will get us started with some basic ExtVal usage.

Bug with Trinidad tables
There’s a bug in ExtVal that can cause some weird behavior in Trinidad’s <tr:table> component. Only the first row will be populated with data, and other rows will not show any data. This happens only when a Facelets composite component is used to add the columns to the table—exactly what we do in our example application. The bug can be found in the JIRA bug tracker for ExtVal at https://issues.apache.org/jira/browse/EXTVAL-77.. There’s a workaround for the bug that we can use until it gets fixed. Be warned that this workaround may have other side effects.
This workaround is shown in the following code snippet, in which we have created a class called DevStartupListener:

public class DevStartupListener extends AbstractStartupListener {
@Override
protected void init() {

ExtValContext.getContext().addGlobalProperty(ExtValRendererProxy.KEY, null, true);
}
}

The required imports are in the org.apache.myfaces.extensions.validator.core package and subpackages. Register this class as a phase listener in the faces-config.xml file:

<lifecycle>
<phase-listener>inc.monsters.mias.workaround.DevStartupListener</phase-listener>

</lifecycle>

You’re all set, and the <tr:table> will now act as expected. Don’t forget to remove this workaround if the bug gets fixed in a future release of ExtVal.

Basic usage

After setting up ExtVal, the basic usage is very simple. Let’s explore a simple example in our MIAS application. In our Kid.java entity, we have some JPA annotations that map the properties of the Kid bean to a database table. Let’s take a closer look at the lastName property of our Kid bean:

@Column(name = "LAST_NAME", nullable = false, length = 30)
private String lastName;

The @Column annotation maps the lastName property to the LAST_NAME column in the database. It also shows some information that is derived from the table definition in the database. nullable = false means the database won’t accept an empty value in this field, and length = 30 means that no more than 30 characters can be stored in the corresponding database column. This information could be used for validation in our View layer. If we hadn’t used ExtVal, we would have added a required="true" attribute to the input element in our EditKid.xhtml page. We also would have added a <tr:validateLength > component to the input component, or we could have set the maximumLength attribute. But all of these things would have been a duplication of information and logic, and would thus break the DRY principle.

With ExtVal, we don’t have to duplicate this information anymore. Whenever ExtVal encounters a nullable = false setting, it will automatically add a required="true" attribute to the corresponding input element. In the same way, it will translate the length = 30 from the @Column annotation into a maximumLength attribute on the input component. The next screenshot shows ExtVal in action. (Note that all validators, and the required and maximumLength attributes were removed from the JSF code before the screenshot was taken.) The really nice thing about this example is that the validations created by ExtVal make use of Trinidad’s client-side validation capabilities. In other words, the error message is created within the user’s web browser before any input is sent to the server.

Apache MyFaces 1.2 Web Application Development

Complementing JPA annotations

It’s nice that we can reuse our JPA annotations for validation. But the chances are that not all validation that we want can be expressed in JPA annotations. For that reason, ExtVal offers a set of extra annotations that we can add to our beans to complement the implicit validation constraints that ExtVal derives from JPA annotations. These annotations are a part of the myfaces-extval-propertyvalidation-1.2.x.jar library. For example, if we want to add a minimum length to the lastName fi eld, we could use the @Length annotation as follows:

@Length(minimum = 5)

@Column(name = "LAST_NAME", nullable = false, length = 30)
private String lastName;

Note that if, for some reason, we couldn’t use the length = 30 setting on the @Column annotation, the @Length annotation also has a maximum property that can be set. The @Length annotation can be imported from the org.apache.myfaces.extensions.validator.baseval.annotation package, which is where the other annotations that ExtVal offers are also located. The following image shows the minimum length validation in action:

Apache MyFaces 1.2 Web Application Development

As the example in the screenshot shows, setting a minimum input length of five characters for a name might not be a good idea. However, that’s an entirely different discussion

Using ExtVal annotations for standard JSF validators

For each of the validator components that is a part of the JSF standard, there is an annotation in ExtVal’s Property Validation library. These are covered briefly in the following subsections.

Note that ExtVal will automatically use any overridden versions of the standard validators, if they are present in the project.

Defining length validation

For the length validation of input strings, the @Length annotation can be used, as shown in the previous example. This annotation relies on the javax.faces.validator.LengthValidator to implement the validation. The following table lists the available properties:

Property

Type

Explanation

minimum

int

The minimum length (inclusive) in characters of the input string

maximum

int

The maximum length (inclusive) of the input string in characters

Defining double range validation

To validate if a double value is within a certain range, the @DoubleRange annotation can be used, which delegates the implementation of the validation to the javax.faces.validator.DoubleRangeValidator validator. See the following table for the available properties:

Property

Type

Explanation

minimum

double

The minimum value (inclusive) of the double input

maximum

double

The maximum value (inclusive)of the double input

Defining long range validation

What @DoubleRange annotation does for doubles, the @LongRange annotation does for long values. It uses javax.faces.validator.LongRangeValidator for the implementation:

Property

Type

Explanation

minimum

long

The minimum value (inclusive) of the long input

maximum

long

The maximum value (inclusive) of the long input

Defining required fields

The example given at the beginning of this section showed how ExtVal can create a required="true" attribute based on an @Column annotation with the nullable = false setting. If it is not possible to use this setting, ExtVal also has an alternative @Required annotation . Just add this annotation to a field to make it required

Using ExtVal’s additional annotations

Apart from the annotations that correspond to the standard JSF validators, some additional annotations exist in the Property Validation module that perform other validations. These are listed in the following subsections.

Whereas the validations based on the JSF standard validators use the error messages provided by the JSF validators, the additional validations cannot use standard messages from JSF. Therefore, standard messages are provided by ExtVal. Should you want to use your own message, all additional annotations have a validationErrorMsgKey property that can be used to assign a message key for the error message. We’ll discuss custom error messages in more detail later in this article.

Defining pattern-based validation

Validation with regular expressions is very powerful, and is very usable for validating phone numbers, postal codes, tax numbers, and any other data that has to fit in a certain pattern. Regular expression-based validation can be added by using the @Pattern annotation. For example, to allow only letters and spaces in the firstName field, we could write:

@Pattern(value="[A-Za-z ]*")
@Column(name = "FIRST_NAME", nullable = false, length = 30)

private String firstName;

For completeness, the following table lists the arguments of the @Pattern annotation:

Property

Type

Required

Explanation

value

String[]

Required

Array of regular expression patterns. Beware if you add more than one pattern that the input must match all patterns. It is easy to make any input invalid by using two patterns that are mutually exclusive.

validatonErrorMsgKey

String

Optional

Optional key for alternative error message.

Apache MyFaces 1.2 Web Application Development Building next-generation web applications with JSF and Facelets
Published: March 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Using custom validators

ExtVal also allows us to use any custom JSF validator that implements the javax.faces.validator.Validator interface. For this purpose, we can use the @Validator annotation. Let’s have a look at another example. Assume that we would allow kids to have all sorts of first names, except “Bart”. We could write a fairly simple JSF validator for that like this:

package inc.monsters.mias.validators;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

public class NoBartValidator implements Validator {

public FirstNameValidator() {
}

public void validate(FacesContext ctx, UIComponent comp, Object value) throws ValidatorException {

if("Bart".equals(value)) {
FacesMessage fm = new FacesMessage("First name Bart is not allowed.");
 throw new ValidatorException(fm);
}
}
}

Normally, we would put the NoBartValidator.java file in our web project, eventually resulting in a NoBartValidator.class in our WAR file. As we’re going to use this class in an ExtVal annotation, which is in our Entities JAR, we have to put the validator class there as well.

Instead of putting our custom validator class in our Entities JAR as proposed, creating a separate validation module into which we can place our custom validator(s) is perhaps a better idea. This gives us the chance to easily reuse our custom validator(s) in other projects. In this case, we put our custom validator(s) in a separate JAR and add that JAR to our collection of libraries.

The custom validator does not have to be configured in the faces-config.xml file as is normally the case with JSF validators. ExtVal will add the custom validator at runtime, when needed.

Now that we have prepared our custom validator, we can use it with the @Validator annotation in our entities. For example, in the Kid entity:

package inc.monsters.mias.data;

import inc.monsters.mias.validators.NoBartValidator;

...

public class Kid implements Serializable {


...

@Column(name = "FIRST_NAME")
@Validator(NoBartValidator.class)
private String firstName;

...

}

Note that we have to import the NoBartValidator class, because it is referenced in the @Validator annotation in a typesafe way.

Reusing validation

If multiple fields share the same validation rules, then according to the DRY principle, we should not repeat these validations for all of the fields. For this reason, the @JoinValidation annotation exists. As a simple example, we could reuse the validation rules of the lastName field for the firstName field, as shown here:

@Column(name = "FIRST_NAME")
@JoinValidation(value="lastName")
private String firstName;

@Length(minimum = 5)
@Column(name = "LAST_NAME", nullable = false, length = 30)

private String lastName;

In this example, all validation of the lastName field will be copied to the firstName field by ExtVal.

Although it is nice to have a way to prevent the repetition of the same validation, care should be taken when using the @JoinValidation annotation. The example that we just saw makes sense, as we can say that first names and last names are both names, and for that reason can share their validation. But sharing of validation between semantically unrelated fields can lead to messy code. As a rule of thumb, validation should only be shared if it makes sense semantically.

The @JoinValidation annotation can also be used to reuse validations in other beans. To do so, there are multiple ways to refer to the property in another bean, as follows:

  • Property chain reference: If the other bean has a relationship to the current one, a “property chain” can be constructed to reach the property that we want to refer to. For example, if our Kid bean had a parent property (and a getParent() method) that referred to a Parent bean, which also has a lastName property, that property could be reached by the property chain parent.lastName. Therefore, we could write @JoinValidation(value="parent.lastName").
    There are a lot of reasons why a property chain might not be possible. The bean to reference might not have any relation to the bean where the validation is to be reused, or the relationship might be “one to many”—for example, a Manager bean that has a List of Employees. For that reason, two alternatives to the property chain exist, as listed next.
  • Expression language reference: Assume that there is a managed bean (or Spring bean) in the View project, with the name employee. In this case, we could write—@JoinValidation(value="#{employee.lastName}").
    We should realize that Expression Language reference breaks the separation of concerns of the Model-View-Controller (MVC) pattern. By using a JSF EL expression in the Model layer, the Model layer now has a detailed knowledge of the (implementation of) the View layer. In this example, this means that if the name of the employee bean changes in the future, the reference to it in the Model layer will have to be updated too. And if the same Model is to be used with different View layers, you’ll have to make sure that all of the View layers have an employee bean. For that reason, the use of Expression Language reference should be avoided.
  • Static reference: To overcome the problems of Expression Language reference, static reference can be used as an alternative. With static reference, a property is referenced by the fully-qualified name of its parent class, followed by the property name, separated by a colon. So to reference the lastName property of Employee bean, the complete annotation could look as follows: @JoinValidation(value="inc.monsters.mias.data.Employee:lastName"). Note that static reference is not available in the second release of ExtVal. So as long as there is no stable third release, we have to use a snapshot build of ExtVal 1.2.3 to be able to use static reference.

To summarize, the easiest way to reference another validation for reuse is, of course, local reference; but that’s only possible for properties within the same bean. To refer to a property outside the current bean, property chain reference is a clean and easy solution in some cases, but it can’t be used in all cases. For the cases where local or property chain reference can’t be used, static reference is the best choice. Expression Language reference could be used as an alternative, but it comes at the price of breaking the MVC separation of concerns—a reason to avoid it if possible.

Applying cross validation

Cross validation is the validation of one value against another value that is entered by the user, or a value that is already somewhere in the Model. An example in our MIAS application could be that the “last scared” date for a kid can never be before the birth date of that kid. This type of validation is often hard to implement, especially because JSF doesn’t offer validators for this. ExtVal offers a set of annotations that lets us define cross validations easily, and in an elegant way. For example, to implement the constraint on the “last scared” date just described, we simply add a single annotation to the lastScared property:

@Temporal(TemporalType.DATE)
@Column(name = "LAST_SCARED")
@DateIs(type = DateIsType.after, valueOf = "birthDate")

private Date lastScared;

Now it won’t be possible to add a scare date that is before the birth date. The following subsections cover all of the cross validations that are available “out of the box” in ExtVal.

As with the @JoinValidation annotation, cross validation needs a mechanism to refer to other properties that take part in the cross validation. ExtVal cross validation annotations use the same referencing mechanisms that @JoinValidation uses. However, static references do not make sense for cross validation, so the static reference option is not available for the cross validation annotations.

Using cross validation for date values

Cross validation for dates is possible with the @DateIs annotation. The most important arguments for @DateIs are listed in the following table:

Argument

Required

Description

type

Optional

The type of date comparison that has to be executed. The possible values are:

  • DateIsType.before: The date to be validated has to be before the referenced date.
  • DateIsType.after: The date to be validated has to be after the referenced date.
  • DateIsType.same: The date to be validated has to be the same as the referenced date. This is the default setting. So if you leave out the type setting, the "same" comparison will be used.

valueOf

Required

The referenced date. This should be the name of a property that contains the date to which the date should be compared. More than one date can be referenced. If that is desired, the valueOf argument should be set to an array of Strings, where each String references one other value.

See the information box in the Applying Cross Validation section for information about the available referencing strategies.

notBeforeErrorMsgKey

Optional

The key that will be used to look up the error message if a DateIsType.before rule is violated. The default key is wrong_date_not_before.

notAfterErrorMsgKey

Optional

The key that will be used to look up the error message if a DateIsType.after rule is violated. The default key is wrong_date_not_after.

notEqualErrorMsgKey

Optional

The key that will be used to look up the error message if a DateIsType.same rule is violated. The default key is wrong_date_not_equal.

errorMessageDateStyle

Optional

The date format style for dates that are used within an error message. It should be one of the date style constants defined in java.text.DateFormat. The default is DateFormat.MEDIUM.

validationErrorMsgKey

Optional

Can be used to set the key to look up a more general error message. Is empty by default.

Using cross validation based on equality

Two annotations exist to check if two values are equal or not—@Equals and @NotEquals. The attributes for both annotations are the same, as listed in the following table:

Argument

Required

Description

value

Required

The value(s) to compare to. It can be a single String or an array of Strings if comparison to multiple values is required.

See the information box in the Applying Cross Validation section for information about the available referencing strategies.

validationErrorMsgKey

Optional

Can be used to override the default key that is used to look up the error message in a message bundle in case the validation fails. The default value is:

  • duplicated_content_required for @Equals
  • duplicated_content_denied for @NotEquals

As an example, the @Equals annotation could be used to verify a “retype password” field:

@Equals(value = "password",
validationErrorMsgKey = "retype_password")
private String retypePassword;

Making a value required conditionally

Another form of cross validation is making a field required only if one or more other fields are not empty. This can easily be accomplished with the @RequiredIf annotation. The arguments of the @RequiredIf annotation are shown in the following table:

Argument

Required

Description

valueOf

Required

The value(s) that should be checked to be empty or not. This can be a single String or an array of Strings if comparison to multiple values is required.

See the information box in the Applying Cross Validation section for information about the available referencing strategies.

is

Optional

One of RequiredIfType.not_empty or RequiredIfType.empty. If set to RequiredIfType.empty, the field will be required only if the referenced field is empty. The default is RequiredIfType.not_empty.

validationErrorMsgKey

Optional

Can be used to override the default key that is used to look up the error message in a message bundle, in case the validation fails. The default value is empty_field.

This section discussed the annotations that are a part of ExtVal’s Property Validation module. From version *.*.3 onwards, ExtVal also offers a Bean Validation module that allows us to use annotations from the Bean Validation (JSR 303) standard, instead of, or in combination with, ExtVal’s own annotations. See the Using Bean Validation section for more information. In the following section, we will see how we can customize all of the error messages generated by ExtVal.

Creating custom error messages

With ExtVal, the error messages shown if validation fails come from different sources, as follows:

  • For validation that is derived from JPA annotations, ExtVal relies on the standard JSF validators. Hence, the error messages shown are the standard JSF error messages. The way in which standard JSF messages can be overridden is defined in the JSF standard. This is covered in the next section, Overriding standard JSF error messages.
  • The ExtVal annotations @Length, @DoubleRange, @LongRange, and @Required also rely on standard JSF mechanisms for implementing the validation. So these will lead to standard JSF error messages as well.
  • All other ExtVal annotations have their own default error messages. How to override these ExtVal messages is covered in the Overriding ExtVal default error messages section.

Overriding standard JSF error messages

Although overriding standard JSF messages is not a feature of ExtVal, we cover it briefly here for convenience. Standard JSF error messages can be overridden by configuring a message bundle in the faces-config.xml file, and adding certain key/value pairs to that message bundle. In our MIAS application, we’ve configured a message bundle as follows:

<message-bundle>inc.monsters.mias.Messages</message-bundle>

This means that the JSF framework expects a file called Messages.properties to be present in the inc/monsters/mias directory. In that file, we can configure our custom messages. For example, to override the default message for required fields that are left empty, we could add the following to the file:

javax.faces.component.UIInput.REQUIRED = Hey dude, this field is required!

The important thing here is the key —javax.faces.component.UIInput.REQUIRED. A list of all JSF error messages with their keys can be found in Appendix D. This appendix also shows the placeholders that can be used in the message texts. The placeholders will be replaced by the label of the input element that the message is related to, and examples of good values or maximum and minimum values where applicable.

Overriding ExtVal default error messages

ExtVal always looks in a fixed location for a message bundle; it doesn’t care about the JSF message bundle configuration. To change a message, we can either put a message bundle in that default location, or we can tell ExtVal to look for the message bundle in another location. The default message bundle that ExtVal looks for is validation_messages in the org.apache.myfaces.extensions.validator.custom package. Of course, we could create that package within our application and put a validation_messages.properties file there. But wouldn’t it be great if we could just use our application-wide message bundle? That’s possible by telling ExtVal to look somewhere else for a message bundle. This is done by setting a context parameter in the web.xml file as follows:

<context-param>
<param-name>org.apache.myfaces.extensions.validator.CUSTOM_MESSAGE_BUNDLE</param-name>
<param-value>inc.monsters.mias.Messages</param-value>
</context-param>

Now we can put custom messages in our own Messages.properties file. To override the default error message for the @Pattern annotation, we could add:

no_match = Pattern not matched

But in this case, “pattern not matched” might be a bit too generic as an error message for end users. ExtVal lets us override the error message on a per-field basis, allowing us to define more specific error messages. For example, we could have a firstName field with a pattern that allows only letters. Now we would like to have a message saying that only letters are allowed in names. In that case, we could write:

@Column(name = "FIRST_NAME")
@Pattern(value="[A-Za-z]*", validationErrorMsgKey="name_characters")

private String firstName;

Now if we add a name_characters key to our message bundle, we can set our customized, field-specific message:

name_characters = A name may only contain letters

Alternative options for customized messages
The options that we just saw are not the only options that ExtVal offers for creating custom error messages. However, the presented options are very useful in most cases and allow us to use a single message bundle for the whole application.
However, there may be reasons why we need other ways to customize the messages. For example, if we were creating a standalone validation module for reuse in more than one project, setting a context parameter in the web.xml file is not an option. In that case, implementing our own MessageResolver is probably a good idea. This is fairly simple to do by just subclassing the DefaultValidationErrorMessageResolver class from the org.apache.myfaces.extensions.validator.core.validation.message.resolver package. Only the getCustomBaseName() method needs to be overridden, and this should return the fully-classified name of the message bundle. ExtVal offers even more alternatives. Should you want to look for other ways to provide custom messages, the ExtVal wiki is a good place to start: http://wiki.apache.org/ myfaces/Extensions/Validator/Getting_Started/Custom_Messages.

Summary

This article introduced MyFaces Extensions Validator, or ExtVal for short. After the installation of ExtVal, we saw that no configuration is needed to get started, based on standard JPA annotations. After that, we had a look at the extra annotations that ExtVal adds to facilitate more validation options and to enable cross validation. We saw how we can combine ExtVal with custom JSF validators. We also looked into creating custom error messages.


If you have read this article you may be interested to view :


Apache MyFaces 1.2 Web Application Development Building next-generation web applications with JSF and Facelets
Published: March 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Bart Kummel

Bart Kummel is an experienced Java EE developer and architect living in The Netherlands. He studied Electrical Engineering at the Delft University of Technology and graduated with honor from the Hogeschool van Amsterdam, with a specialization in Technical Computer Sciences. After his study, he started as a developer of embedded software for a security systems manufacturer in Amsterdam. After four years of developing embedded software, Bart switched to enterprise software and started at Transfer Solutions B.V., based in Leerdam. Transfer Solutions is a consulting company that specializes in Oracle and Java technology.

As a consultant for Transfer Solutions, Bart gained a lot of experience with Java EE. For different clients, he has fulfilled the roles of developer or architect in small as well as large projects. In those projects, he has worked with various frameworks and standards, including Oracle’s Application Development Framework (ADF), Apache MyFaces, EclipseLink, JavaServer Faces (JSF), Java Persistence API (JPA), and Java Messaging Service (JMS). Bart also teaches courses in Object Orientation, UML, Java, Java EE, and ADF, at Transfer Solutions’ education department.

Bart published an article on EclipseLink in the Dutch Java Magazine, and presented the use of AJAX capabilities in Oracle’s ADF Faces at the ODTUG Kaleidoscope conference in 2007.

The link to his website is www.bartkummel.net

Books From Packt


Drupal 6 Performance Tips
Drupal 6 Performance Tips

AJAX and PHP: Building Modern Web Applications 2nd Edition
AJAX and PHP: Building Modern Web Applications 2nd Edition

Joomla! 1.5 Multimedia
Joomla! 1.5 Multimedia

jQuery 1.4 Reference Guide
jQuery 1.4 Reference Guide

Drupal 6 Attachment Views
Drupal 6 Attachment Views

Grok 1.0 Web Development
Grok 1.0 Web Development

Tomcat 6 Developer's Guide
Tomcat 6 Developer's Guide

Apache Roller 4.0 – Beginner's Guide
Apache Roller 4.0 – Beginner's Guide


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
b
d
x
T
n
X
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software