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>
完成。如果您打算自定义消息,可以通过requiredMessage
和validatorMessage
属性,或者自定义<message-bundle>
。