自定义验证器抛出 ValidatorException,但它不会阻止表单提交

Custom validator throws ValidatorException, but it doesn't block form submit

我正在尝试使用验证器检查注册时电子邮件是否已存在于数据库中。为此,我这样写我的表格:

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

我还有一个 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;
    }

}

问题是,当我尝试提交表单时,ExistenceEmailValidator 中的 Sysout 打印 "It throws" 当他必须这样做时,似乎正确地抛出了异常。然而,在任何情况下,即使电子邮件地址已经存在,也会提交表单并在数据库中注册用户。

那么,我的验证器有什么问题?我使用正确吗?

感谢您的回答!

您可以直接使用自定义验证器

下面link中的BaluC已经给出了您需要的答案: JSF 2.0 validation in actionListener or action method

在 bean 上使用绑定 属性 是不好的做法:

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

您确实正确地抛出了 ValidatorException。但是您随后会立即捕获它并用一个空的 catch 块完全抑制它。请参阅下面我的评论。

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.
}

摆脱那个试探。这没有意义。让异常消失,以便 JSF 可以处理它。

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