Custom JSF validator for required fields

JSF components implementing EditableValueHolder interface have two attributes ‘ required’ and ‘ requiredMessage’ – a flag indicating that the user is required to input / select not empty value and a text for validation message. We can use that, but it’s not flexible enough, we can’t parameterize the message directly in view (facelets or jsp) and we have to do something for a proper message customization. What is about a custom validator attached to any required field? We will write one. At first we need to register such validator in a tag library.

<?xml version='1.0'?>
<facelet-taglib version='2.0' ... >
    <namespace>http://ip.client/ip-jsftoolkit/validator</namespace>
    <tag>
        <tag-name>requiredFieldValidator</tag-name>
        <validator>
            <validator-id>ip.client.jsftoolkit.RequiredFieldValidator</validator-id>
        </validator>
        <attribute>
            <description>Resource bundle name for the required message</description>
            <name>bundle</name>
            <required>false</required>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <description>Key of the required message in the resource bundle</description>
            <name>key</name>
            <required>false</required>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <description>Label string for the required message</description>
            <name>label</name>
            <required>false</required>
            <type>java.lang.String</type>
        </attribute>
    </tag>
</facelet-taglib>

We defined three attributes in order to achieve a high flexibility. A simple using would be

<h:outputLabel for='myInput' value='#{text['myinput']}'/>
<h:inputText id='myInput' value='...'>
    <jtv:requiredFieldValidator label='#{text['myinput']}'/>
</h:inputText>

The validator class itself is not difficult. Dependent on the ‘ key’ parameter (key of the required message) and the ‘ label’ parameter (text of the corresponding label) there are four cases how the message gets acquired.

/**
 * Validator for required fields.
 */
@FacesValidator(value = RequiredFieldValidator.VALIDATOR_ID)
public class RequiredFieldValidator implements Validator
{
    /** validator id */
    public static final String VALIDATOR_ID = 'ip.client.jsftoolkit.RequiredFieldValidator';

    /** default bundle name */
    public static final String DEFAULT_BUNDLE_NAME = 'ip.client.jsftoolkit.validator.message';

    private String bundle;
    private String key;
    private String label;

    @Override
    public void validate(FacesContext facesContext,
        UIComponent component, Object value) throws ValidatorException
    {
        if (!UIInput.isEmpty(value)) {
           return;
        }

        String message;
        String bundleName;

        if (bundle == null) {
           bundleName = DEFAULT_BUNDLE_NAME;
        } else {
           bundleName = bundle;
        }

        if (key == null && label == null) {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName),
                  'jsftoolkit.validator.emptyMandatoryField.1');
        } else if (key == null && label != null) {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName),
                  'jsftoolkit.validator.emptyMandatoryField.2', label);
        } else if (key != null && label == null) {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName), key);
        } else {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName), key, label);
        }

        throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_WARN, message, StringUtils.EMPTY));
       
        // getter / setter
        ... 
    }
}

MessageUtils is an utility class to get ResourceBundle and message text. We also need two text in the resource bundle (property file)

jsftoolkit.validator.emptyMandatoryField.1=Some required field is not filled in.
jsftoolkit.validator.emptyMandatoryField.2=The required field '{0}' is not filled in.

and the following context parameter in web.xml

<context-param>
    <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
    <param-value>true</param-value>
</context-param>

This solution is not ideal because we need to define the label text (like #{text['myinput']}) twice and to attach the validator to each field to be validated. A better and generic validator for multiple fields will be presented in the next post. Stay tuned!

Reference: Custom JSF validator for required fields from our JCG partner Oleg Varaksin at the Thoughts on software development blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


seven − = 1



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close