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.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


− three = 3



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
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.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books