提交的值在validate() 实现中仅作为value 参数可用。
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
Object oldValue = ((UIInput) component).getValue();
if (value != null ? value.equals(oldValue) : oldValue == null) {
// Value has not changed.
return;
}
// Continue validation here.
}
另一种方法是将Validator 设计为ValueChangeListener。只有当值真正改变时才会调用它。它有点 hacky,但它可以完成你真正需要的工作。
<h:inputText ... valueChangeListener="#{uniqueValueValidator}" />
或
<h:inputText ...>
<f:valueChangeListener binding="#{uniqueValueValidator}" />
</h:inputText>
与
@ManagedBean
public class UniqueValueValidator implements ValueChangeListener {
@Override
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
UIInput input = (UIInput) event.getComponent();
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
// Validate newValue here against DB or something.
// ...
if (invalid) {
input.setValid(false);
context.validationFailed();
context.addMessage(input.getClientId(context),
new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please enter unique value", null));
}
}
}
请注意,您不能在那里抛出ValidatorException,这就是为什么需要手动将组件和面孔上下文设置为无效并手动为组件添加消息的原因。 context.validationFailed() 将强制 JSF 跳过更新模型值并调用操作阶段。