tags:

views:

41

answers:

3

I am very new to JSF/Java but I wanted to know if anyone knows a good way to create a custom validation controller. I have a lot of forms in my web application with fields that overlap such as First Name, SSN, or email. I wanted to create a Controller that would handle all of these validations and messages.

Is this a good idea? I have been looking online on documentation but it looks like every example I have found they put the validation method within a specific bean and not in a controller.

Any examples / links to examples / advice on a good way of implementing something like this would be great.

I am using JSF 2.0

A: 

I think the following example will work for you: http://viralpatel.net/blogs/2009/02/javaserver-faces-jsf-validation-tutorial-error-handling-jsf-validator.html . It even has a email address validator as an example.

e.g., from that page:

Write a validator by implementing the Validator interface:

package net.viralpatel.jsf.helloworld;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

public class EmailValidator implements Validator{
    public void validate(FacesContext context, UIComponent component, Object value)
            throws ValidatorException {

        String email = (String) value;

        if(!email.contains("@")) {
            FacesMessage message = new FacesMessage();
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            message.setSummary("Email is not valid.");
            message.setDetail("Email is not valid.");
            context.addMessage("userForm:Email", message);
            throw new ValidatorException(message);
        }
    }
}

Then, you need a reference to this validator in your faces-config.xml

    <validator>
        <validator-id>emailValidator</validator-id>
        <validator-class>net.viralpatel.jsf.helloworld.EmailValidator</validator-class>
    </validator>

Then, use it!

<h:inputText id="Email" value="#{userBean.email}" required="true">
    <f:validator validatorId="emailValidator" />
</h:inputText>
The Alchemist
If you are using JSF >=2.0, I recommend BalusC approach because you don't have to modify your `faces-config.xml` file. However, if you're stuck with JSF <2.0, you'll need to do the above.
The Alchemist
+1  A: 

This is not the normal approach. You should delegate the controlling task to the FacesServlet. It's doing its job perfectly fine. If all what you want is decoupling validation from the managed bean, then just create a standalone class which implements javax.faces.validator.Validator. To get it to loaded automagically, just mark it with the appropriate @FacesValidator annotation.

Here's a kickoff example:

package com.example;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

@FacesValidator(value="ssnValidator")
public class SSNValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        // Implement as you did originally in the bean method.
    }

}

You can declare it as <f:validator> in any UIInput component as follows:

<h:inputText value="#{bean.ssn}">
    <f:validator validatorId="ssnValidator" />
</h:inputText>
BalusC
+1  A: 

JSF validators are defined on a per-component basis and are best used to stop junk getting into your model. Avoid trying to use them to perform validation where the value of one component affects the validity of another.

If you're on a JEE6 server, have a look at JSR 303 Bean Validation.

From the JSF 2.0 spec:

Version 2 of the specification introduces support for JSR 303 Bean Validation. A JSF implentation must support JSR 303 Bean Validation if the environment in which the JSF runtime is included requires JSR 303 Bean Validation. Currently the only such environment is when JSF is included in a Java EE 6 runtime.

The spec goes on to define how and in which phases of the JSF lifecycle bean validation is performed.

McDowell