JSF2.0>多字段验证 - 属性设置不正确

时间:2013-12-18 10:01:59

标签: jsf jsf-2 validation

我正在尝试在JSF2.0下实现多字段(例如两个inputText-fields)验证。 遗憾的是,验证器中没有设置属性。

行为如下:

当我提交两个输入字段的第一个条目时,验证器中的属性为空。在第二次提交中,值正确填充。在第3次提交中,我可以看到第2个请求的值,但不是第3个请求的值。 这是一种非常奇怪的行为。

在下面你可以看到我的测试代码。

TestValidator.class

@FacesValidator(value="testValidator")
public class TestValidator implements Validator {
    @Override
    public void validate(FacesContext context, UIComponent component, Object value)   throws ValidatorException {

        UIInput c1 = (UIInput) context.getViewRoot().findComponent("input1");
        if (c1 != null) {
            Object s1 = (Object) c1.getSubmittedValue();
        }

        UIInput c2 = (UIInput) context.getViewRoot().findComponent("input2");
        if (c2 != null) {
            Object s2 = (Object) c2.getSubmittedValue();
        }

        String c5 = (String) component.getAttributes().get("input1");
        String c6 = (String) component.getAttributes().get("input2");
    }
}

我尝试以两种不同的方式获取属性。不幸的是没有成功。 参数 value 始终设置正确。

test.xhtml

这是我第一次尝试将 f:attribute 附加到第二个inputText-field

<h:form id="test">

<h:inputText value="#{testModelBean.input1}" maxlength="10" size="4">
</h:inputText>

<h:inputText value="#{testModelBean.input2}" maxlength="10" size="4">

    <f:validator validatorId="testValidator" />

    <f:attribute name="input1" value="#{testModelBean.input1}" />
    <f:attribute name="input2" value="#{testModelBean.input2}" />

</h:inputText>

<h:commandButton action="#{testControllerBean.doAction}" /> 

</h:form>

这是我的第二个 h:inputHidden

<h:form id="test">

<h:inputHidden value="true">
       <f:validator validatorId="testValidator" />
       <f:attribute name="input1" value="#{testModelBean.input1}" />
       <f:attribute name="input2" value="#{testModelBean.input2}" />
    </h:inputHidden>

<h:inputText value="#{testModelBean.input1}" maxlength="10" size="4">
</h:inputText>

<h:inputText value="#{testModelBean.input2}" maxlength="10" size="4">
</h:inputText>

<h:commandButton action="#{testControllerBean.doAction}" /> 

</h:form>

在这两种情况下,行为都与上面提到的相同。

我的TestModelBean很简单

TestModelBean.class

@ManagedBean(name="testModelBean")
@SessionScoped
public class TestModelBean implements Serializable {

    private String input1;
    private String input2;

    public String getInput1() {
        return input1;
    }
    public void setInput1(String input1) {
        this.input1 = input1;
    }
    public String getInput2() {
        return input2;
    }
    public void setInput2(String input2) {
        this.input2 = input2;
    }

}

我的TestControllerBean也很简单:

TestControllerBean.class

@ManagedBean(name="testControllerBean")
@SessionScoped
public class TestControllerBean 
implements Serializable {

    public String doAction() {
        return "success";
    }

}

现在我的问题是,如果有人有想法,为什么在每个提交/请求中都没有填充属性。或者有不同的方式来访问属性?我应该关注某个订单(关于DOM或JSF生命周期)吗?

1 个答案:

答案 0 :(得分:1)

您似乎误解了JSF的生命周期。模型值在稍后阶段(更新模型值阶段)更新,而不是JSF验证发生(过程验证阶段)。因此,当您希望获得模型值时,它尚未设置。因此,您可以从@SessionScoped bean中获取旧值

有关JSF生命周期的概述,请参阅Debug JSF lifecycleThe JSF application lifecycle

你怎么能克服这种情况?您可以将完整组件绑定为所需组件的属性,并分别使用UIInput方法UIInput#getValue()UIInput#getSubmittedValue()来获取组件的转换/验证值(对于定位的绑定组件) 之前 JSF组件树中的相关组件)或原始提交的值(对于 JSF组件树中有问题的组件之后的绑定组件)。

总而言之,您需要将代码更改为以下内容:

观点:

<h:inputText value="#{testModelBean.input1}" binding="#{input}" />
<h:inputText value="#{testModelBean.input2}">
    <f:validator validatorId="testValidator" />
    <f:attribute name="input1" value="#{input}" />
</h:inputText>

验证器方法片段:

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    UIInput input = (UIInput)component.getAttributes().get("input");
    String inputString = (String)input.getValue();
    //etc.
}

请参阅JSF getValue() v.s. getSubmittedValue()JSF doesn't support cross-field validation, is there a workaround?JSF validate on submit form以获取概述。

相关问题