Developing Web Applications using JavaServer Faces: Part 2

4 min read

JSF Validation

Earlier in this article, we discussed how the required attribute for JSF input fields allows us to easily make input fields mandatory.

If a user attempts to submit a form with one or more required fields missing, an error message is automatically generated.

The error message is generated by the <h:message> tag corresponding to the invalid field. The string First Name in the error message corresponds to the value of the label attribute for the field. Had we omitted the label attribute, the value of the fields id attribute would have been shown instead. As we can see, the required attribute makes it very easy to implement mandatory field functionality in our application.

Recall that the age field is bound to a property of type Integer in our managed bean. If a user enters a value that is not a valid integer into this field, a validation error is automatically generated.

Of course, a negative age wouldn’t make much sense, however, our application validates that user input is a valid integer with essentially no effort on our part.

The email address input field of our page is bound to a property of type String in our managed bean. As such, there is no built-in validation to make sure that the user enters a valid email address. In cases like this, we need to write our own custom JSF validators.

Custom JSF validators must implement the javax.faces.validator.Validator interface. This interface contains a single method named validate(). This method takes three parameters: an instance of javax.faces.context.FacesContext, an instance of javax.faces.component.UIComponent containing the JSF component we are validating, and an instance of java.lang.Object containing the user entered value for the component. The following example illustrates a typical custom validator.

package com.ensode.jsf.validators;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlInputText;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
public class EmailValidator implements Validator {
public void validate(FacesContext facesContext,
UIComponent uIComponent, Object value) throws
ValidatorException {
Pattern pattern = Pattern.compile("w+@w+.w+");
Matcher matcher = pattern.matcher(
(CharSequence) value);
HtmlInputText htmlInputText = (HtmlInputText) uIComponent;
String label;
if (htmlInputText.getLabel() == null ||
htmlInputText.getLabel().trim().equals("")) {
label = htmlInputText.getId();
} else {
label = htmlInputText.getLabel();
}
if (!matcher.matches()) {
FacesMessage facesMessage =
new FacesMessage(label +
": not a valid email address");
throw new ValidatorException(facesMessage);
}
}
}

In our example, the validate() method does a regular expression match against the value of the JSF component we are validating. If the value matches the expression, validation succeeds, otherwise, validation fails and an instance of javax.faces.validator.ValidatorException is thrown.

The primary purpose of our custom validator is to illustrate how to write custom JSF validations, and not to create a foolproof email address validator. There may be valid email addresses that don’t validate using our validator.

The constructor of ValidatorException takes an instance of javax.faces.application.FacesMessage as a parameter. This object is used to display the error message on the page when validation fails. The message to display is passed as a String to the constructor of FacesMessage. In our example, if the label attribute of the component is not null nor empty, we use it as part of the error message, otherwise we use the value of the component’s id attribute. This behavior follows the pattern established by standard JSF validators.

Before we can use our custom validator in our pages, we need to declare it in the application’s faces-config.xml configuration file. To do so, we need to add a <validator> element just before the closing </faces-config> element.

<validator>
<validator-id>emailValidator</validator-id>
<validator-class>
com.ensode.jsf.validators.EmailValidator
</validator-class>
</validator>

The body of the <validator-id> sub element must contain a unique identifier for our validator. The value of the <validator-class> element must contain the fully qualified name of our validator class.

Once we add our validator to the application’s faces-config.xml, we are ready to use it in our pages.

In our particular case, we need to modify the email field to use our custom validator.

<h:inputText id="email" label="Email Address"
required="true" value="#{RegistrationBean.email}">
<f:validator validatorId="emailValidator"/>
</h:inputText>

All we need to do is nest an <f:validator> tag inside the input field we wish to have validated using our custom validator. The value of the validatorId attribute of <f:validator> must match the value of the body of the <validator-id> element in faces-config.xml.

At this point we are ready to test our custom validator.

When entering an invalid email address into the email address input field and submitting the form, our custom validator logic was executed and the String we passed as a parameter to FacesMessage in our validator() method is shown as the error text by the <h:message> tag for the field.

Packt

Share
Published by
Packt

Recent Posts

Top life hacks for prepping for your IT certification exam

I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…

3 years ago

Learn Transformers for Natural Language Processing with Denis Rothman

Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…

3 years ago

Learning Essential Linux Commands for Navigating the Shell Effectively

Once we learn how to deploy an Ubuntu server, how to manage users, and how…

3 years ago

Clean Coding in Python with Mariano Anaya

Key-takeaways:   Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…

3 years ago

Exploring Forms in Angular – types, benefits and differences   

While developing a web application, or setting dynamic pages and meta tags we need to deal with…

3 years ago

Gain Practical Expertise with the Latest Edition of Software Architecture with C# 9 and .NET 5

Software architecture is one of the most discussed topics in the software industry today, and…

3 years ago