1

I am trying to use a validator to check at the registration if the email already exists in the database. For this I write my form like this :

<h:form>
    ...
    <h:inputText id="email" class="form-control" value="#{usersBean.email}">
        <f:validator binding="#{existenceEmailValidator}"/>
    </h:inputText> 
    <h:message for="email"/>
    ...
</h:form>

I also have an ExistenceEmailValidator class :

package com.ml.validators;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import com.ml.service.UsersService;

@ManagedBean
@RequestScoped
public class ExistenceEmailValidator implements Validator {

    private static final String EMAIL_EXISTE_DEJA = "Cette adresse email est déjà utilisée";

    @ManagedProperty( "#{usersService}" )
    private UsersService        usersService;

    @Override
    public void validate( FacesContext context, UIComponent component, Object value ) throws ValidatorException {

        String email = (String) value;

        try {
            if ( usersService.existingMail( email ) ) {
                System.out.println( "It throws !" );
                throw new ValidatorException(
                        new FacesMessage( FacesMessage.SEVERITY_ERROR, EMAIL_EXISTE_DEJA, null ) );
            } else {
            }
        } catch ( Exception e ) {

        }
    }

    public UsersService getUsersService() {
        return usersService;
    }

    public void setUsersService( UsersService usersService ) {
        this.usersService = usersService;
    }

}

The problem is that when I try to submit the form, the Sysout in ExistenceEmailValidator print "It throws" when he has to so the Exception seems to be thrown corretly. However in every cases, the form is submitted and the user is registered in the database even if the email address already exists.

So, what is the problem with my validator ? Am I using it correctly ?

Thanks for your answers !

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Jean DELI
  • 38
  • 1
  • 7
  • **Never** do such thinks like ` } catch ( Exception e ) { }`. You have to log the exception or handle it in an other way – Jens Feb 18 '16 at 14:03
  • What is `UsersService`? As the name suggests, it appears to be a service or EJB. If it is the case, then you will need to inject it using its own annotation (`@EJB` for an EJB, `@Autowired` for a Spring service). `@ManagedProperty` will not work in that case. Besides, you know that JSF and Spring MVC cannot reside in the same house. Therefore, tagging both together does not make much sense. – Tiny Feb 18 '16 at 14:23
  • Thank you for your answer. I just don't understand why @ManagedProperty doesn't work in that case ? Besides the call to the method of UsersService (which is a service) seems to be done correctly (if statement works fine) – Jean DELI Feb 18 '16 at 14:32
  • Not only `@ManagedProperty` but also `@ManagedBean` and `@RequestScoped` will be sitting silently, if beans are managed by Spring. You will need `@Component` and `@Scope("request")` or better choose another bean management framework like CDI, if allowed. Spring and JSF managed beans are predecessors of CDI. – Tiny Feb 18 '16 at 14:40
  • That you initially tagged [spring-mvc] on this [jsf] question is worrisome. To avoid fundamental misunderstandings and future mistakes, here's food for thought: http://stackoverflow.com/q/18744910 – BalusC Feb 18 '16 at 15:28

2 Answers2

2

You're indeed correctly throwing a ValidatorException. But you're then immediately catching it and completely suppressing it with an empty catch block. See my comments below.

try {
    if ( usersService.existingMail( email ) ) {
        System.out.println( "It throws !" );
        throw new ValidatorException(
                new FacesMessage( FacesMessage.SEVERITY_ERROR, EMAIL_EXISTE_DEJA, null ) );
    } else {
    }
} catch ( Exception e ) {
    // Here the ValidatorException is being caught.
    // And you're doing nothing with it.
    // So, code continues as if nothing exceptional happened.
}

Get rid of that try-catch. It doesn't make sense. Let the exception go so JSF can deal with it.

if ( usersService.existingMail( email ) ) {
    System.out.println( "It throws !" );
    throw new ValidatorException(
            new FacesMessage( FacesMessage.SEVERITY_ERROR, EMAIL_EXISTE_DEJA, null ) );
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you very much for your clear answer. I mad changes and this works now perfectly. Thanks for the advice ! – Jean DELI Feb 18 '16 at 15:56
-1

You can directly use a Custom Validator.

The answer to your needs is already given by BaluC within the following link: JSF 2.0 validation in actionListener or action method

Using binding on a bean property is bad practice :

How does the 'binding' attribute work in JSF? When and how should it be used?

Community
  • 1
  • 1
  • 1
    Using either `` or `` will not make an essential functional difference in this case. The statement, "*Using binding on a bean property is bad practice*" does not apply here, since no property is being bound to a bean. – Tiny Feb 18 '16 at 15:23