Using Converters, Listeners, and Validators
We are working on a fresh, updated Jakarta EE Tutorial. This section hasn’t yet been updated. |
The previous chapter described components and explained how to add them to a web page. This chapter provides information on adding more functionality to the components through converters, listeners, and validators.
-
Converters are used to convert data that is received from the input components. Converters allow an application to bring the strongly typed features of the Java programming language into the String-based world of HTTP servlet programming.
-
Listeners are used to listen to the events happening in the page and perform actions as defined.
-
Validators are used to validate the data that is received from the input components. Validators allow an application to express constraints on form input data to ensure that the necessary requirements are met before the input data is processed.
Using the Standard Converters
The Jakarta Faces implementation provides a set of Converter
implementations that you can use to convert component data.
The purpose of conversion is to take the String-based data coming in from the Servlet API and convert it to strongly typed Java objects suitable for the business domain.
For more information on the conceptual details of the conversion model, see Conversion Model.
The standard Converter
implementations are located in the jakarta.faces.convert
package.
Normally, converters are implicitly assigned based on the type of the EL expression pointed to by the value of the component.
However, these converters can also be accessed by a converter ID.
Converter Classes and Converter IDs shows the converter classes and their associated converter IDs.
Class in the jakarta.faces.convert Package | Converter ID |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A standard error message is associated with each of these converters.
If you have registered one of these converters onto a component on your page and the converter is not able to convert the component’s value, the converter’s error message will display on the page.
For example, the following error message appears if BigIntegerConverter
fails to convert a value:
{0} must be a number consisting of one or more digits
In this case, the {0}
substitution parameter will be replaced with the name of the input component on which the converter is registered.
Two of the standard converters (DateTimeConverter
and NumberConverter
) have their own tags, which allow you to configure the format of the component data using the tag attributes.
For more information about using DateTimeConverter
, see Using DateTimeConverter.
For more information about using NumberConverter
, see Using NumberConverter.
The following section explains how to convert a component’s value, including how to register other standard converters with a component.
Converting a Component’s Value
To use a particular converter to convert a component’s value, you need to register the converter onto the component. You can register any of the standard converters in one of the following ways.
-
Nest one of the standard converter tags inside the component’s tag. These tags are
f:convertDateTime
andf:convertNumber
, which are described in Using NumberConverter, respectively. -
Bind the value of the component to a managed bean property of the same type as the converter. This is the most common technique.
-
Refer to the converter from the component tag’s
converter
attribute, specifying the ID of the converter class. -
Nest an
f:converter
tag inside of the component tag, and use either thef:converter
tag’sconverterId
attribute or itsbinding
attribute to refer to the converter.
As an example of the second technique, if you want a component’s data to be converted to an Integer
, you can simply bind the component’s value to a managed bean property.
Here is an example:
Integer age = 0;
public Integer getAge(){ return age;}
public void setAge(Integer age) {this.age = age;}
The data from the h:inputText
tag in the this example will be converted to a java.lang.Integer
value.
The Integer
type is a supported type of NumberConverter
.
If you don’t need to specify any formatting instructions using the f:convertNumber
tag attributes, and if one of the standard converters will suffice, you can simply reference that converter by using the component tag’s converter
attribute.
You can also nest an f:converter
tag within the component tag and use either the converter tag’s converterId
attribute or its binding
attribute to reference the converter.
The converterId
attribute must reference the converter’s ID.
Here is an example that uses one of the converter IDs listed in Converter Classes and Converter IDs:
<h:inputText value="#{loginBean.age}">
<f:converter converterId="jakarta.faces.Integer" />
</h:inputText>
Instead of using the converterId
attribute, the f:converter
tag can use the binding
attribute.
The binding
attribute must resolve to a bean property that accepts and returns an appropriate Converter
instance.
You can also create custom converters and register them on components using the f:converter
tag.
For details, see Creating and Using a Custom Converter.
Using DateTimeConverter
You can convert a component’s data to a java.util.Date
by nesting the convertDateTime
tag inside the component tag.
The convertDateTime
tag has several attributes that allow you to specify the format and type of the data.
Attributes for the f:convertDateTime Tag lists the attributes.
Here is a simple example of a convertDateTime
tag:
<h:outputText value="#{cashierBean.shipDate}">
<f:convertDateTime type="date" dateStyle="full" />
</h:outputText>
When binding the DateTimeConverter
to a component, ensure that the managed bean property to which the component is bound is of type java.util.Date
.
In the preceding example, cashierBean.shipDate
must be of type java.util.Date
.
The example tag can display the following output:
Saturday, September 21, 2013
You can also display the same date and time by using the following tag in which the date format is specified:
<h:outputText value="#{cashierBean.shipDate}">
<f:convertDateTime pattern="EEEEEEEE, MMM dd, yyyy" />
</h:outputText>
If you want to display the example date in Spanish, you can use the locale
attribute:
<h:outputText value="#{cashierBean.shipDate}">
<f:convertDateTime dateStyle="full"
locale="es"
timeStyle="long" type="both" />
</h:outputText>
This tag would display the following output:
jueves 24 de octubre de 2013 15:07:04 GMT
Refer to the "Customizing Formats" lesson of the Java Tutorial at https://docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html for more information on how to format the output using the pattern
attribute of the convertDateTime
tag.
Attribute | Type | Description |
---|---|---|
|
|
Used to bind a converter to a managed bean property. |
|
|
Defines the format, as specified by |
|
|
Used with composite components. Refers to one of the objects within the composite component inside which this tag is nested. |
|
|
|
|
|
Custom formatting pattern that determines how the date/time string should be formatted and parsed.
If this attribute is specified, See Type Attribute and Default Pattern Values for the default values when |
|
|
Defines the format, as specified by |
|
|
Time zone in which to interpret any time information in the |
|
|
Specifies whether the string value will contain a date, a time, or both.
Valid values are: See Type Attribute and Default Pattern Values for additional information. |
Type Attribute | Class | Default When Pattern Is Not Specified |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Using NumberConverter
You can convert a component’s data to a java.lang.Number
by nesting the convertNumber
tag inside the component tag.
The convertNumber
tag has several attributes that allow you to specify the format and type of the data.
Attributes for the f:convertNumber Tag lists the attributes.
The following example uses a convertNumber
tag to display the total prices of the contents of a shopping cart:
<h:outputText value="#{cart.total}">
<f:convertNumber currencySymbol="$" type="currency"/>
</h:outputText>
When binding the NumberConverter
to a component, ensure that the managed bean property to which the component is bound is of a primitive type or has a type of java.lang.Number
.
In the preceding example, cart.total
is of type double
.
Here is an example of a number that this tag can display:
$934
This result can also be displayed by using the following tag in which the currency pattern is specified:
<h:outputText id="cartTotal" value="#{cart.total}">
<f:convertNumber pattern="$####" />
</h:outputText>
See the "Customizing Formats" lesson of the Java Tutorial at https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html for more information on how to format the output by using the pattern
attribute of the convertNumber
tag.
Attribute | Type | Description |
---|---|---|
|
|
Used to bind a converter to a managed bean property. |
|
|
ISO 4217 currency code, used only when formatting currencies. |
|
|
Currency symbol, applied only when formatting currencies. |
|
|
Used with composite components. Refers to one of the objects within the composite component inside which this tag is nested. |
|
|
Specifies whether formatted output contains grouping separators. |
|
|
Specifies whether only the integer part of the value will be parsed. |
|
|
|
|
|
Maximum number of digits formatted in the fractional part of the output. |
|
|
Maximum number of digits formatted in the integer part of the output. |
|
|
Minimum number of digits formatted in the fractional part of the output. |
|
|
Minimum number of digits formatted in the integer part of the output. |
|
|
Custom formatting pattern that determines how the number string is formatted and parsed. |
|
|
Specifies whether the string value is parsed and formatted as a |
Registering Listeners on Components
An application developer can implement listeners as classes or as managed bean methods.
If a listener is a managed bean method, the page author references the method from either the component’s valueChangeListener
attribute or its actionListener
attribute.
If the listener is a class, the page author can reference the listener from either an f:valueChangeListener
tag or an f:actionListener
tag and nest the tag inside the component tag to register the listener on the component.
Referencing a Method That Handles an Action Event and Referencing a Method That Handles a Value-Change Event explain how a page author uses the valueChangeListener
and actionListener
attributes to reference managed bean methods that handle events.
This section explains how to register a NameChanged
value-change listener and a BookChange
action listener implementation on components.
The Duke’s Bookstore case study includes both of these listeners.
Registering a Value-Change Listener on a Component
A page author can register a ValueChangeListener
implementation on a component that implements EditableValueHolder
by nesting an f:valueChangeListener
tag within the component’s tag on the page.
The f:valueChangeListener
tag supports the attributes shown in Attributes for the f:valueChangeListener Tag, one of which must be used.
Attribute | Description |
---|---|
|
References the fully qualified class name of a |
|
References an object that implements |
The following example shows a value-change listener registered on a component:
<h:inputText id="name"
size="30"
value="#{cashierBean.name}"
required="true"
requiredMessage="#{bundle.ReqCustomerName}">
<f:valueChangeListener
type="ee.jakarta.tutorial.dukesbookstore.listeners.NameChanged" />
</h:inputText>
In the example, the core tag type
attribute specifies the custom NameChanged
listener as the ValueChangeListener
implementation registered on the name
component.
After this component tag is processed and local values have been validated, its corresponding component instance will queue the ValueChangeEvent
associated with the specified ValueChangeListener
to the component.
The binding
attribute is used to bind a ValueChangeListener
implementation to a managed bean property.
This attribute works in a similar way to the binding
attribute supported by the standard converter tags.
See Binding Component Values and Instances to Managed Bean Properties for more information.
Registering an Action Listener on a Component
A page author can register an ActionListener
implementation on a command component by nesting an f:actionListener
tag within the component’s tag on the page.
Similarly to the f:valueChangeListener
tag, the f:actionListener
tag supports both the type
and binding
attributes.
One of these attributes must be used to reference the action listener.
Here is an example of an h:commandLink
tag that references an ActionListener
implementation:
<h:commandLink id="Duke" action="bookstore">
<f:actionListener
type="ee.jakarta.tutorial.dukesbookstore.listeners.LinkBookChangeListener" />
<h:outputText value="#{bundle.Book201}"/>
</h:commandLink>
The type
attribute of the f:actionListener
tag specifies the fully qualified class name of the ActionListener
implementation.
Similarly to the f:valueChangeListener
tag, the f:actionListener
tag also supports the binding
attribute.
See Binding Converters, Listeners, and Validators to Managed Bean Properties for more information about binding listeners to managed bean properties.
In addition to the actionListener
tag that allows you register a custom listener onto a component, the core tag library includes the f:setPropertyActionListener
tag.
You use this tag to register a special action listener onto the ActionSource
instance associated with a component.
When the component is activated, the listener will store the object referenced by the tag’s value
attribute into the object referenced by the tag’s target
attribute.
The bookcatalog.xhtml
page of the Duke’s Bookstore application uses f:setPropertyActionListener
with two components: the h:commandLink
component used to link to the bookdetails.xhtml
page and the h:commandButton
component used to add a book to the cart:
<h:dataTable id="books"
value="#{store.books}"
var="book"
headerClass="list-header"
styleClass="list-background"
rowClasses="list-row-even, list-row-odd"
border="1"
summary="#{bundle.BookCatalog}" >
...
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.ItemTitle}"/>
</f:facet>
<h:commandLink action="#{catalog.details}"
value="#{book.title}">
<f:setPropertyActionListener target="#{requestScope.book}"
value="#{book}"/>
</h:commandLink>
</h:column>
...
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.CartAdd}"/>
</f:facet>
<h:commandButton id="add"
action="#{catalog.add}"
value="#{bundle.CartAdd}">
<f:setPropertyActionListener target="#{requestScope.book}"
value="#{book}"/>
</h:commandButton>
</h:column>
...
</h:dataTable>
The h:commandLink
and h:commandButton
tags are within an h:dataTable
tag, which iterates over the list of books.
The var
attribute refers to a single book in the list of books.
The object referenced by the var
attribute of an h:dataTable
tag is in page scope.
However, in this case you need to put this object into request scope so that when the user activates the commandLink
component to go to bookdetails.xhtml
or activates the commandButton
component to go to bookcatalog.xhtml
, the book data is available to those pages.
Therefore, the f:setPropertyActionListener
tag is used to set the current book object into request scope when the commandLink
or commandButton
component is activated.
In the preceding example, the f:setPropertyActionListener
tag’s value
attribute references the book
object.
The f:setPropertyActionListener
tag’s target
attribute references the value expression requestScope.book
, which is where the book
object referenced by the value
attribute is stored when the commandLink
or the commandButton
component is activated.
Using the Standard Validators
Jakarta Faces technology provides a set of standard classes and associated tags that page authors and application developers can use to validate a component’s data. The Validator Classes lists all the standard validator classes and the tags that allow you to use the validators from the page.
Validator Class | Tag | Function |
---|---|---|
|
|
Registers a bean validator for the component. |
|
|
Allows cross-field validation by enabling class-level bean validation on CDI-based backing beans. |
|
|
Checks whether the local value of a component is within a certain range. The value must be floating-point or convertible to floating-point. |
|
|
Checks whether the length of a component’s local value is within a certain range.
The value must be a |
|
|
Checks whether the local value of a component is within a certain range.
The value must be any numeric type or |
|
|
Checks whether the local value of a component is a match against a regular expression from the |
|
|
Ensures that the local value is not empty on an |
All of these validator classes implement the Validator
interface.
Component writers and application developers can also implement this interface to define their own set of constraints for a component’s value.
Similar to the standard converters, each of these validators has one or more standard error messages associated with it.
If you have registered one of these validators onto a component on your page and the validator is unable to validate the component’s value, the validator’s error message will display on the page.
For example, the error message that displays when the component’s value exceeds the maximum value allowed by LongRangeValidator
is as follows:
{1}: Validation Error: Value is greater than allowable maximum of "{0}"
In this case, the {1}
substitution parameter is replaced by the component’s label or id
, and the {0}
substitution parameter is replaced with the maximum value allowed by the validator.
See Displaying Error Messages with the h:message and h:messages Tags for information on how to display validation error messages on the page when validation fails.
Instead of using the standard validators, you can use Bean Validation to validate data.
If you specify bean validation constraints on your managed bean properties, the constraints are automatically placed on the corresponding fields on your applications web pages.
See Introduction to Jakarta Bean Validation for more information.
You do not need to specify the validateBean
tag to use Bean Validation, but the tag allows you to use more advanced Bean Validation features.
For example, you can use the validationGroups
attribute of the tag to specify constraint groups.
You can also create and register custom validators, although Bean Validation has made this feature less useful. For details, see Creating and Using a Custom Validator.
Validating a Component’s Value
To validate a component’s value using a particular validator, you need to register that validator on the component. You can do this in one of the following ways.
-
Nest the validator’s corresponding tag (shown in The Validator Classes) inside the component’s tag. Using Validator Tags explains how to use the
validateLongRange
tag. You can use the other standard tags in the same way. -
Refer to a method that performs the validation from the component tag’s
validator
attribute. -
Nest a validator tag inside the component tag, and use either the validator tag’s
validatorId
attribute or itsbinding
attribute to refer to the validator.
See Referencing a Method That Performs Validation for more information on using the validator
attribute.
The validatorId
attribute works similarly to the converterId
attribute of the converter
tag, as described in Converting a Component’s Value.
Keep in mind that validation can be performed only on components that implement EditableValueHolder
, because these components accept values that can be validated.
Using Validator Tags
The following example shows how to use the f:validateLongRange
validator tag on an input component named quantity
:
<h:inputText id="quantity" size="4" value="#{item.quantity}">
<f:validateLongRange minimum="1"/>
</h:inputText>
<h:message for="quantity"/>
This tag requires the user to enter a number that is at least 1.
The validateLongRange
tag also has a maximum
attribute, which sets a maximum value for the input.
The attributes of all the standard validator tags accept EL value expressions.
This means that the attributes can reference managed bean properties rather than specify literal values.
For example, the f:validateLongRange
tag in the preceding example can reference managed bean properties called minimum
and maximum
to get the minimum and maximum values acceptable to the validator implementation, as shown in this snippet from the guessnumber-faces
example:
<h:inputText id="userNo"
title="Type a number from 0 to 10:"
value="#{userNumberBean.userNumber}">
<f:validateLongRange minimum="#{userNumberBean.minimum}"
maximum="#{userNumberBean.maximum}"/>
</h:inputText>
The following f:validateRegex
tag shows how you might ensure that a password is from 4 to 10 characters long and contains at least one digit, at least one lowercase letter, and at least one uppercase letter:
<f:validateRegex pattern="((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,10})"
for="passwordVal"/>
Referencing a Managed Bean Method
A component tag has a set of attributes for referencing managed bean methods that can perform certain functions for the component associated with the tag. These attributes are summarized in Component Tag Attributes That Reference Managed Bean Methods.
Attribute | Function |
---|---|
|
Refers to a managed bean method that performs navigation processing for the component and returns a logical outcome |
|
Refers to a managed bean method that handles action events |
|
Refers to a managed bean method that performs validation on the component’s value |
|
Refers to a managed bean method that handles value-change events |
Only components that implement ActionSource
can use the action
and actionListener
attributes.
Only components that implement EditableValueHolder
can use the validator
or valueChangeListener
attributes.
The component tag refers to a managed bean method using a method expression as a value of one of the attributes.
The method referenced by an attribute must follow a particular signature, which is defined by the tag attribute’s definition in the Jakarta Faces Facelets Tag Library documentation.
For example, the definition of the validator
attribute of the inputText
tag is the following:
void validate(jakarta.faces.context.FacesContext,
jakarta.faces.component.UIComponent, java.lang.Object)
The following sections give examples of how to use the attributes.
Referencing a Method That Performs Navigation
If your page includes a component, such as a button or a link, that causes the application to navigate to another page when the component is activated, the tag corresponding to this component must include an action
attribute.
This attribute does one of the following:
-
Specifies a logical outcome
String
that tells the application which page to access next -
References a managed bean method that performs some processing and returns a logical outcome
String
The following example shows how to reference a navigation method:
<h:commandButton value="#{bundle.Submit}"
action="#{cashierBean.submit}" />
See Writing a Method to Handle Navigation for information on how to write such a method.
Referencing a Method That Handles an Action Event
If a component on your page generates an action event, and if that event is handled by a managed bean method, you refer to the method by using the component’s actionListener
attribute.
The following example shows how such a method could be referenced:
<h:commandLink id="Duke" action="bookstore"
actionListener="#{actionBean.chooseBookFromLink}">
The actionListener
attribute of this component tag references the chooseBookFromLink
method using a method expression.
The chooseBookFromLink
method handles the event when the user clicks the link rendered by this component.
See Writing a Method to Handle an Action Event for information on how to write such a method.
Referencing a Method That Performs Validation
If the input of one of the components on your page is validated by a managed bean method, refer to the method from the component’s tag by using the validator
attribute.
The following simplified example from The guessnumber-cdi CDI Example shows how to reference a method that performs validation on inputGuess
, an input component:
<h:inputText id="inputGuess"
value="#{userNumberBean.userNumber}"
required="true" size="3"
disabled="#{userNumberBean.number eq userNumberBean.userNumber ...}"
validator="#{userNumberBean.validateNumberRange}">
</h:inputText>
The managed bean method validateNumberRange
verifies that the input value is within the valid range, which changes each time another guess is made.
See Writing a Method to Perform Validation for information on how to write such a method.
Referencing a Method That Handles a Value-Change Event
If you want a component on your page to generate a value-change event and you want that event to be handled by a managed bean method instead of a ValueChangeListener
implementation, you refer to the method by using the component’s valueChangeListener
attribute:
<h:inputText id="name"
size="30"
value="#{cashierBean.name}"
required="true"
valueChangeListener="#{cashierBean.processValueChange}" />
</h:inputText>
The valueChangeListener
attribute of this component tag references the processValueChange
method of CashierBean
by using a method expression.
The processValueChange
method handles the event of a user entering a name in the input field rendered by this component.
Writing a Method to Handle a Value-Change Event describes how to implement a method that handles a ValueChangeEvent
.