如果值已更改,如何签入验证器?

时间:2012-05-28 17:58:41

标签: validation jsf default-value

我知道我可以通过UIInput#getValue()获得旧值。

但是在很多情况下,字段绑定到bean值,我想获得默认值,如果输入等于默认值,我不需要验证。

如果某个字段具有唯一约束并且您有一个编辑表单,这非常有用 验证将始终失败,因为在检查约束方法中,它将始终找到自己的值,从而验证为false。

一种方法是使用<f:attribute>将该默认值作为属性传递,并在验证器内部进行检查。但是有更简单的内置方式吗?

1 个答案:

答案 0 :(得分:11)

提交的值仅在value实现中以validate()参数的形式提供。

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。然后只有在值真正改变时才会调用它。这有些笨拙,但它确实能满足您的需求。

<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,这就是为什么需要手动将组件和faces上下文设置为无效并手动添加组件的消息。 context.validationFailed()将强制JSF跳过更新模型值并调用操作阶段。