Customized required/@NotNull validation in JSF 1.2

Leave a comment

September 14, 2010 by huionn

After 2 weeks of JSF programming, I hit the first roadblock – customized validation for required field. Due to JSF architecture, a field will be validated if it is not null/not empty. In other words, if a field is null or empty, it will not be validated (except JSF built in required validation). However in my work, I need to validate the required field for if user clicks button A, but skip the validation if user clicks button B. This conditional validation cannot be fulfilled with JSF built in validation.

From what I read, this limitation has been fixed in JSF 2.0. Unfortunately, many JSF 2.0 support are still in beta.

There is a project providing a workaround – http://code.google.com/p/commons-validator-ext/
This is the blog of the project creator – http://www.jroller.com/hasant/entry/jsf_bypassable_client_and_server
Honestly, I cannot truly understand how it works and it has dependency on other libraries (I am afraid of its uncertainty):

“In addition, i have created a RequiredValidatorChecker JSF component which is being added to form dynamically by our form renderer itself. RequiredValidatorChecker component’s mission is easy but critical. It will traverse the form’s component tree at necessary phases(ApplyRequest phase –> processDecodes method and ProcessValidations phase –> processValidators method), if hits a commons required validator of any component, calls commons validator’s validate method to make required validation for that component’s value.”

On the other hand, it mentioned where the problem lies in UIInput.validateValue()

protected void validateValue(FacesContext context, Object value) {
// If our value is valid, enforce the required property if present
if (isValid && isRequired && isEmpty(value)) {
// THROW A REQUIRED VALIDATION MESSAGE
}
// If our value is valid and not empty, call all validators
if (isValid && !isEmpty(value)) {
if (validators exists) {
// CALL CALIDATORS
}
}
}

I also found that richfaces overrides this behavior in its input components: validation will still be applied on empty value if it is typeof org.richfaces.validator.FacesBeanValidator

try {
    if (validator instanceof FacesBeanValidator
        || !isEmpty(newValue)) {
        validator.validate(context, this, newValue);
    }
} catch (ValidatorException ve) {…

faces-config.xml
<component>
    <description><![CDATA[<p>Represents an HTML <code>input</code> element
      of type <code>text</code>.</p>]]></description>
    <display-name>Input Text</display-name>
    <component-type>javax.faces.HtmlInputText</component-type>
    <component-class>org.richfaces.component.html.HtmlInputText</component-class>
  </component>

Following the same way, I override the behavior with

try {
    // validate even if the newValue is empty
    validator.validate(context, this, newValue);
} catch (ValidatorException ve) {…

This is a simpler solution although hardly a better one – each input component need to be overridden for required validation and certain validator may fail with potential null value. Still… I choose this solution because

“Do The Simplest Thing That Could Possibly Work” – XP mantra


[edit] It seems <rich:beanValidator summary="Invalid name"/> of richfaces is better solution. It can reuse Hibernate Validator annotations.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: