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

How to skip validation if previous validator failed?

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;
    }
    
    // ...
    
  • 使用<o:validator> of JSF utility library OmniFaces。它支持延迟评估 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>.