首页 文章

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

提问于
浏览
35

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

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

2 回答

  • 56

    我见过并使用过的最简单的自定义方法是使用 <f:validator> 创建一个 <h:inputHidden> 字段,其中您将所有涉及的组件引用为 <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>
    

    (请注意隐藏输入上的 value="true" ;当它为空或空时,实际值实际上不会被触发,具体取决于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();
            // ...
        }
    
    }
    

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

    另见:


    或者,您可以使用第三方标签/组件 . RichFaces例如有一个rich:graphValidator标签,Seam3<s:validateForm>为此,OmniFaces有几个标准的<o:validateXxx>组件,这些都是展示here . OmniFaces使用基于组件的方法,该工作在UIComponent#processValidators()中完成 . 它也允许customizing以这种方式,以便可以实现如下:

    <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>
    

    @ManagedBean
    @RequestScoped
    public class FooValidator implements MultiFieldValidator {
    
        @Override
        public boolean validateValues(FacesContext context, List<UIInput> components, List<Object> values) {
            // ...
        }
    }
    

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

  • 1

    这里没有提到Apache ExtVal .

    其中有一些交叉验证(可能有用的其他验证):

    https://cwiki.apache.org/confluence/display/EXTVAL/Property+Validation+Usage#PropertyValidationUsage-CrossValidation

相关问题