JSF不支持跨领域验证,是否有解决方法?

Jon*_*her 35 validation jsf jsf-2

JSF 2.0只允许您验证一个字段的输入,例如检查它是否是一定长度.它不允许您有一个表单,"输入城市和州,或只输入邮政编码".

你是怎么得到这个的?我只对涉及JSF验证阶段的答案感兴趣.我对管理Bean中的验证逻辑不感兴趣.

Bal*_*usC 57

我见过和使用的最简单的自定义方法是创建一个<h:inputHidden>字段,<f:validator>其中您引用所有涉及的组件<f:attribute>.如果待验证组件之前声明它,则可以在验证器中获取提交的值UIInput#getSubmittedValue().

例如

<h:form>
    <h:inputHidden id="foo" value="true">
        <f:validator validatorId="fooValidator" />
        <f:attribute name="input1" value="#{input1}" />
        <f:attribute name="input2" value="#{input2}" />
        <f:attribute name="input3" value="#{input3}" />
    </h:inputHidden>
    <h:inputText binding="#{input1}" value="#{bean.input1}" />
    <h:inputText binding="#{input2}" value="#{bean.input2}" />
    <h:inputText binding="#{input3}" value="#{bean.input3}" />
    <h:commandButton value="submit" action="#{bean.submit}" />
    <h:message for="foo" />
</h:form>
Run Code Online (Sandbox Code Playgroud)

(请注意value="true"隐藏输入;实际值实际上无关紧要,但请记住,验证器在null或空时不一定会被触发,具体取决于JSF版本和配置)

@FacesValidator(value="fooValidator")
public class FooValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        UIInput input1 = (UIInput) component.getAttributes().get("input1");
        UIInput input2 = (UIInput) component.getAttributes().get("input2");
        UIInput input3 = (UIInput) component.getAttributes().get("input3");
        // ...

        Object value1 = input1.getSubmittedValue();
        Object value2 = input2.getSubmittedValue();
        Object value3 = input3.getSubmittedValue();
        // ...
    }

}
Run Code Online (Sandbox Code Playgroud)

如果<h:inputHidden> 待验证组件之后声明,则所涉及组件的值已经转换和验证,您应该通过UIInput#getValue()或者UIInput#getLocalValue()(或者UIInput不是isValid())来获取它们.

也可以看看:


或者,您可以使用第三方标签/组件.RichFaces的例如有<rich:graphValidator>这个标记,Seam3<s:validateForm>这一点,并OmniFaces有几个标准<o:validateXxx>对于这里面都展示组件在这里.OmniFaces使用基于组件的方法来完成工作UIComponent#processValidators().它还允许以这种方式定制它,以便可以如下实现上述目的:

<h:form>
    <o:validateMultiple id="foo" components="input1 input2 input3" validator="#{fooValidator}" />
    <h:inputText id="input1" value="#{bean.input1}" />
    <h:inputText id="input2" value="#{bean.input2}" />
    <h:inputText id="input3" value="#{bean.input3}" />
    <h:commandButton value="submit" action="#{bean.submit}" />
    <h:message for="foo" />
</h:form>
Run Code Online (Sandbox Code Playgroud)

@ManagedBean
@RequestScoped
public class FooValidator implements MultiFieldValidator {

    @Override
    public boolean validateValues(FacesContext context, List<UIInput> components, List<Object> values) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

唯一的区别是它返回a boolean并且消息应该被指定为message属性in <o:validateMultiple>.