Custom validation of required input fields in JSF

Kim Schiller's picture
by Kim Schiller on June 12, 2016

The premise of a JSF Validator (javax.faces.validator.Validator) is that by default it will only be invoked whenever a value is entered in an associated input field. This makes sense, since validating an empty or unchanged value is mostly just a waste of CPU cycles.

Now suppose you need to do validation of multiple required fields or simply want to customize your validator. Then the "required" attribute you can put on your tag or the <f:validateRequired /> might not be the best option. For one thing, it does not allow you to validate fields in conjunction with each other.
So you would probably look at creating a custom validator, that does the required check as well as your custom validations. But wait... without a value, your validator won't be executed.

Validating empty fields

So you need the validator to be called even when the value knowingly is empty. In order to make that work, the JSF 2.x framework does provides a context parameter that you can add to your web.xml:

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

This has the effect, that every validator will be called even without a value. Now it is important that your custom validator does a check for an empty input value. This is, of course, pretty trivial, and could be done like this in your validate method: 

public void validate(FacesContext facesContext, UIComponent uiComponent, Object value) {
    if (!((String) value).isEmpty()){....}
}

Handle empty strings as Null

But this could also be done a little simpler, by having JSF convert any empty string into null using this context parameter:

<context-param>
    <param-name>avax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

Now the initial check inside your validate method could look like this:

public void validate(FacesContext facesContext, UIComponent uiComponent, Object value) {
    if (value != null){....}
}

Nice and clean.