JSF不支持跨域验证,是否有解决方法? [英] JSF doesn't support cross-field validation, is there a workaround?

查看:130
本文介绍了JSF不支持跨域验证,是否有解决方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JSF 2.0仅允许您在一个字段上验证输入,例如检查是否有一定长度.它不允许您使用输入城市和州名,或仅输入邮政编码"的形式.

JSF 2.0 only allows you to validate the input on one field, like check to see if it's a certain length. It doesn't allow you to have a form that says, "enter city and state, or enter just a zip code."

您如何解决这个问题?我只对涉及JSF验证阶段的答案感兴趣.我对将验证逻辑放入托管Bean没兴趣.

How have you gotten around this? I'm only interested in answers that involve the validation phase of JSF. I'm not interested in putting validation logic in Managed Beans.

推荐答案

到目前为止,我所见和使用的最简单的自定义方法是创建一个带有<f:validator><h:inputHidden>字段,其中您将所有涉及的组件引用为<f:attribute>.如果在要验证的组件之前声明了它,则可以通过

The easiest custom approach I've seen and used as far is to create a <h:inputHidden> field with a <f:validator> wherein you reference all involved components as <f:attribute>. If you declare it before the to-be-validated components, then you can obtain the submitted values inside the validator by 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";实际值实际上并不重要,但请记住,当验证器为null或为空时,不一定会触发该验证器,具体取决于JSF版本和配置)

(please note the value="true" on the hidden input; the actual value actually doesn't matter, but keep in mind that the validator won't necessarily be fired when it's null or empty, depending on the JSF version and configuration)

使用

@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#getLocalValue() (如果UIInput不是 isValid() ).

If you declare the <h:inputHidden> after the to-be-validated components, then the values of the involved components are already converted and validated and you should obtain them by UIInput#getValue() or maybe UIInput#getLocalValue() (in case the UIInput isn't isValid()) instead.

或者,您可以为此使用第三方标签/组件.例如, RichFaces 具有 Seam3 具有> c12> ,而 OmniFaces 具有几个标准的自定义,这样可以实现以下目标:

Alternatively, you can use 3rd party tags/components for that. RichFaces for example has a <rich:graphValidator> tag for this, Seam3 has a <s:validateForm> for this, and OmniFaces has several standard <o:validateXxx> components for this which are all showcased here. OmniFaces uses a component based approach whereby the job is done in UIComponent#processValidators(). It also allows customizing it in such way so that the above can be achieved as below:

<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属性.

The only difference is that it returns a boolean and that the message should be specified as message attribute in <o:validateMultiple>.

这篇关于JSF不支持跨域验证,是否有解决方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆