如果先前的验证器失败,如何跳过验证



Mojarra 2.1

在其中一个验证器失败后,我需要停止验证输入值。下面是我的尝试:

<h:inputText id="filterName" value="#{bean.name}" >
    <f:validator validatorId="simpleNameValidator" />
    <f:validator binding="#{customValidator}" disabled="#{facesContext.validationFailed()}"/>
</h:inputText>

验证器:

public class SimpleNameValidator implements Validator{
    private static final int MAX_LENGHT = 32; 
    @Override
    public void validate(FacesContext context, UIComponent component,
            Object value) throws ValidatorException {
        String v = (String) value;
        FacesMessage msg;
        if(v.equals(StringUtils.EMPTY)){
            msg = new FacesMessage("Name is empty");
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ValidatorException(msg);
        }
        if(v.length() >= MAX_LENGHT){
            msg = new FacesMessage("Name is too long"));
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ValidatorException(msg);
        }
    }
}

public class CustomValidator implements Validator{
    private NameService nameService;
    @Override
    public void validate(FacesContext context, UIComponent component,
            Object value) throws ValidatorException {
        String name = nameService.getName((String) value);
        if(name != null) {
            FacesMessage msg = new FacesMessage("The name already exists");
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ValidatorException(msg);
        }
    }
    public NameService getNameService() {
        return nameService;
    }
    public void setNameService(NameService nameService) {
        this.nameService = nameService;
    }
}

但它没有工作。我不明白为什么没有,因为我显式地指定了第二个验证器的disabled属性。所以,它肯定没有被应用,因为第一个失败了。也许我误解了validationFailed的目的…

你不能解释这种行为并如何解决它吗?

<f:validator disabled>属性是在视图构建时,即验证器即将附加到组件时计算的。在执行验证之前不会对其进行评估。

你可以通过以下方式解决这个问题:

  • validate()方法中,只需通过UIInput#isValid()检查组件是否有效。

    if (!((UIInput) component).isValid()) {
        return;
    }
    // ...
    
  • 使用JSF实用程序库OmniFaces的<o:validator>。它支持对其所有属性中的EL进行延迟求值。下面是一个改进了disabled属性检查的示例。

    <o:validator binding="#{customValidator}" disabled="#{not component.valid}"/>
    

    #{component}指当前的UIComponent实例,在<h:inputXxx>组件的情况下,它是UIInput的实例,因此具有isValid()属性。


与具体问题无关,需求和长度验证可以分别使用required="true"<f:validateRequired><f:validateLength>完成。如果您打算自定义消息,可以通过requiredMessagevalidatorMessage属性,或者自定义<message-bundle>

相关内容

  • 没有找到相关文章

最新更新