An Introduction to JSF: Part 2

Ian Hlavats

December 2009

Standard JSF Validators

The JSF Core tag library also includes a number of built-in validators. These validator tags can also be registered with UI components to verify that required fields are completed by the user-that numeric values are within an acceptable range,and that text values are a certain length. For more specific validation scenarios, we can also write our own custom validators. User input validation happens immediately after data conversion during the JSF request lifecycle.

Validating the Length of a Text Value

JSF includes a built-in validator that can be used to ensure a text value entered by the user is between an expected minimum and maximum length. The following example demonstrates using the <f:validatelength> tag’s minimum and maximum attributes to check that the password entered by the user in the password field is exactly 8 characters long. It also demonstrates how to use the label attribute of certain JSF input components (introduced in JSF 1.2) to render a localizable validation message.

JSF Validation Messages The JSF framework includes predefined validation messages for different input components and validation scenarios. These messages are defined in a message bundle (properties file) including in the JSF implementation jar file. Many of these messages are parameterized, meaning that since JSF 1.2 a UI component’s label can be inserted into these messages to provide more detailed information to the user. The default JSF validation messages can be overridden by specifying the same message bundle keys in the application’s message bundle. We will see an example of customizing JSF validation messages below.

Notice that we also set the maxlength attribute of the <h:inputsecret> tag to limit the input to 8 characters. This does not, however, ensure that the user enters a minimum of 8 characters. Therefore, the <f:validatelength> validator tag is required.

<h:outputLabel value="Please enter a password (must be 8
characters): " />
<h:inputSecret maxlength="8" id="password"
<f:validateLength minimum="8" maximum="8" />
<h:commandButton value="Submit" /><br />
<h:message for="password" errorStyle="color:red" />

JSF 1.2 Components

Validating a Required Field

The following example demonstrates how to use the built-in JSF validators to ensure that a text field is filled out before the form is processed, and that the numeric value is between 1 and 10:

<h:outputLabel value="Please enter a number: " />
<h:inputText id="number" label="Number"
required="#{true}" />
<h:commandButton value="Submit" /><br />
<h:message for="number" errorClass="error" />

The following screenshot demonstrates the result of submitting a JSF form containing a required field that was not filled out. We render the validation error message using an <h:message> tag with a for attribute set to the ID of the text field component. We have also overridden the default JSF validation message for required fields by specifying the following message key in our message bundle. We will discuss message bundles and internationalization (I18N) shortly.

javax.faces.component.UIInput.REQUIRED=Required field.
javax.faces.component.UIInput.REQUIRED_detail=Please fill in this field.

JSF 1.2 Components

Validating a numeric range

The JSF Core <f:validatelongrange> and </f:validatedoublerange> tags can be used to validate numeric user input. The following example demonstrates how to use the <f:validatelongrange> tag to ensure an integer value entered by the user is between 1 and 10.

<h:outputLabel value="Please enter a number between 1 and 10: " />
<h:inputText id="number" value="#{backingBean.number}"
<f:validateLongRange minimum="1" maximum="10" />
<h:commandButton value="Submit" /><br />
<h:message for="number" errorStyle="color:red" />
<h:outputText value="You entered: #{backingBean.number}"
rendered="#{backingBean.number ne null}" />

The following screenshot shows the result of entering an invalid value into the text field. Notice that the value of the text field’s label attribute is interpolated with the standard JSF validation message.

JSF 1.2 Components

Validating a floating point number is similar to validating an integer. The following example demonstrates how to use the value to ensure that a floating point number is between 0.0 and 1.0.

<h:outputLabel value="Please enter a floating point number between
0 and 1: " />
<h:inputText id="number" value="#{backingBean.percentage}"
<f:validateDoubleRange minimum="0.0" maximum="1.0" />
<h:commandButton value="Submit" /><br />
<h:message for="number" errorStyle="color:red" />
<h:outputText value="You entered: "
rendered="#{backingBean.percentage ne null}" />
<h:outputText value="#{backingBean.percentage}"
rendered="#{backingBean.percentage ne null}" >
<f:convertNumber type="percent" maxFractionDigits="2" />

JSF 1.2 Components

Registering a custom validator

JSF also supports defining custom validation classes to provide more specialized user input validation. To create a custom validator, first we need to implement the javax.faces.validator.Validator interface. Implementing a custom validator in JSF is straightforward. In this example, we check if a date supplied by the user represents a valid birthdate. As most humans do not live more than 120 years, we reject any date that is more than 120 years ago. The important thing to note from this code example is not the validation logic itself, but what to do when the validation fails. Note that we construct a FacesMessage object with an error message and then throw a ValidatorException.

package chapter1.validator;

import java.util.Calendar;
import java.util.Date;

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 CustomDateValidator implements Validator {

public void validate(FacesContext context, UIComponent component,
Object object) throws ValidatorException {
if (object instanceof Date) {
Date date = (Date) object;
Calendar calendar = Calendar.getInstance();
calendar.roll(Calendar.YEAR, -120);
if (date.before(calendar.getTime())) {
FacesMessage msg = new FacesMessage();
msg.setSummary("Invalid birthdate: " + date);
msg.setDetail("The date entered is more than 120 years ago.");
throw new ValidatorException(msg);

We have to declare our custom validators in faces-config.xml as follows, giving the validator an ID of customDateValidator:

<description>This birthdate validator checks a date to make sure it
is within the last 120 years.</description>
<display-name>Custom Date Validator</display-name>


Next, we would register our custom validator on a JSF UI component using the tag. This tag has a converterId attribute that expects the ID of a custom converter declared in faces-config.xml. Notice in the following example that we are also registering the standard JSF <f:convertdatetime></f:convertdatetime> converter on the tag. This is to ensure that the value entered by the user is first converted to a java.util.Date object before it is passed to our custom validator.

<h:inputText id="name" value="#{}">
<f:convertDateTime type="date" pattern="M/d/yyyy" />
<f:validator validatorId="customDateValidator" />

Many JSF UI component tags have both a converter and validator attribute that accept EL method expressions. These attributes provides another way to register custom converters and validators implemented in managed beans on UI components.

Internationalization (I18N)

One of the many benefits of the JSF framework is the ability to easily internationalize our applications. The support for internationalization (abbreviated as I18N, short for “I followed by 18 letters followed by N”) in JSF is built on top of the Java platforms existing internationalization framework, so it should be familiar to Java developers who already have some experience with properties files and the java.util.ResourceBundle and java.util.Locale classes.

As the format of date and time, numbers, and currency values can change significantly from one locale to another, JSF conveniently extends Java’s internationalization support to our user interface by making UI components locale aware. For example, in the US, a currency value is formatted as $1,999.99 while in France this value is formatted as 1 999,99 $.

At the root of the UI component tree for each view is the JSF UIViewRoot object. This component is rendered by the tag in our JSF markup, and supports a locale attribute that accepts any valid locale value that can be passed to the constructor of the java.util.Locale class.

Internationalization first requires us to define the locales we are supporting, and to convert text messages and other application resources into locale-specific formats. This process is called localization (L10N). Let’s examine the process of localizing the labels for our UI components in a message bundle for three locales: English (our default locale), French, and Spanish.

What is a Locale?A locale in the context of Java internationalization can be defined in terms of a language, country, and variant. In the simplest case, a locale can be a language such as English, French, or Spanish (for example). These languages are represented using ISO-639 standard language codes, specifically “en”, “fr”, and “sp”. As English is spoken and written differently in various English-speaking countries, the Java I18N framework enables us to refine our support for different locales by qualifying the language with a country code, such as “en_US” for US English speakers, and “en_GB” for British English speakers.Finally, the locale identifier can be further qualified by adding a variant after the country code. A variant is an optional identifier for a vendor’s product, such as an operating system or Web browser, or a variation of the language code, such as the traditional or international form of a language. An example of the locale code for a traditional Spanish speaking Windows user would be “en_ES_Traditional_WIN”. (When there are two variant codes, they should be separated with an underscore and the most important one placed first.)

For demonstration purposes, we will only be supporting the English, French, and Spanish languages and will not be using the language or variant components of the locale code. As our JSF application supports three languages, our localized messages would be stored in three message bundles (.properties files), one per language, named “”, “”, and “”.

To illustrate how message bundles work, let’s take a closer look at our properties files.

The following is an extract from our English message bundle. Keep in mind that these messages will be used in our JSF pages as button and field labels. Validation messages can also be stored in these files.

firstNameLabel=First Name
lastNameLabel=Last Name
dateOfBirthLabel=Date of Birth
phoneNumberLabel=Phone Number
emailAddressLabel=Email Address
countryLabel=Country of Origin
interestsLabel=Relevant Interests

The following is an extract from our French message bundle. Notice that the same keys are defined, but the values are different. The messages have been translated into French for this locale.

lastNameLabel=Nom de famille
dateOfBirthLabel=Date de naissance
countryLabel=Pays d'origine

The following is a sample from our Spanish message bundle. Once again, the keys are the same but the message bundle values have been localized (this time in Spanish).

dateOfBirthLabel=Fecha de nacimiento
phoneNumberLabel=Número de teléfono
emailAddressLabel=Correo electrónico
countryLabel=País de origen

These message bundles are included with our web application and accessed by the JSF framework when a localized message is rendered in the view. As JSF 1.2, there are two ways to make message bundles available to web pages in our JSF applications:

Registering a message bundle (JSF 1.1)

Registering a message bundle in JSF 1.1 requires adding the following XML to the faces-config.xml file:


Notice that we specify the name of the message bundle properties file (without the locale information and without the .properties file extension) for the <message-bundle> element. Next we specify the locales supported by our JSF application in the </locale-config> element, indicating the English (en) is our default locale. The JSF framework will expect the following files to exist on our web application’s classpath:

  • - The default (English) message bundle
  • - The English message bundle
  • – The French message bundle
  • – The Spanish message bundle

To use our message bundles, we need to declare the <f:loadbundle> tag in our JSF pages:

<f:loadBundle var=”bundle” basename=”messages” />
<h:outputText value=”#{bundle.welcomeMessage}” />

The previous example loads a message bundle for the current JSF page into a Map object and stores it in a variable named “bundle” that can be access using EL expressions. The <h:outputtext> tag demonstrates how to lookup and display a string from the message bundle with the key “welcomeMessage”.

As we did not specify the locale attribute on the <f:view> tag, the JSF framework will automatically attempt to determine the locale of the user by examining the browser’s HTTP request headers.

Registering a Message Bundle (JSF 1.2)

Since JSF 1.2, there is another way to use message bundles in our JSF pages. Instead of loading our message bundle on each page using the <f:loadbundle>  tag, we can simply declare our message bundle once in faces-config.xml and use it from any page in our JSF application. The following XML must be added to faces-config.xml to enable this feature:


The previous example loads a message bundle from the file for the locale of the current view and stores it as a Map object named “bundle”. EL expressions can reference this message bundle as they did before using the <f:loadbundle> approach. The benefit of using the <resource-bundle> element in faces-config.xml instead of the </message-bundle> element is that we can now register our message bundle once for the entire JSF application, instead of having to register it on each page.


In this article series, we learned a lot about JavaServer Faces (JSF). We spoke about:

  • Model-View-Controller architecture
  • JSF Request Processing Lifecycle
  • Managed Beans
  • EL Expressions
  • UI Components
  • Validators
  • Internationalization


You've been reading an excerpt of:

JSF 1.2 Components

Explore Title