简体   繁体   English

JSF2跨字段验证失败循环

[英]JSF2 Cross Field Validation Failure Loop

Requirements in an app I'm developing say that when performing a search, the user should not be able to search for City without entering State, and vice versa, they shouldn't be able to search for State without entering City. 我正在开发的应用程序中的要求说,执行搜索时,用户应该在不输入州名的情况下不能搜索城市,反之亦然,他们应该在不输入州名的情况下不能搜索州。

search.xhtml search.xhtml

<h:inputText id="city" binding="#{city}" value="#{search.city}" validator="#{search.validateCity}">
  <f:attribute name="state" value="#{state}"/>
</h:inputText>

<h:inputText id="state" binding="#{state}" value="#{search.state}" validator="#{search.validateState}">
  <f:attribute name="city" value="#{city}"/>
</h:inputText>

Search.java Search.java

public void validateCity(FacesContext context, UIComponent component, Object convertedValue) {
    UIInput stateComponent = (UIInput) component.getAttributes().get("state");
    String state = (String) stateComponent.getValue();
    if(convertedValue.toString().length() > 0) {
        if(state.length() < 1) {
            throw new ValidatorException(new FacesMessage("Please enter State."));
        }
    }
}

public void validateState(FacesContext context, UIComponent component, Object convertedValue) {
    UIInput cityComponent = (UIInput) component.getAttributes().get("city");
    String city = (String) cityComponent.getValue();
    if(convertedValue.toString().length() > 0) {
        if(city.length() < 1) {
            throw new ValidatorException(new FacesMessage("Please enter City."));
        }
    }
}

I've simplified down my code to show what I attempted with the standard cross field validation method. 我简化了代码,以展示我尝试使用标准跨字段验证方法进行的操作。 However, the problem I'm hitting is that in the validation phase, both City and State are showing Validation errors, I'm guessing because the two validators are getting in each others' way and therefore creating a loop of failure. 但是,我遇到的问题是,在验证阶段,城市和州都显示了验证错误,我猜这是因为两个验证者互相干扰,因此造成了失败循环。

Is there a workaround I can use to get around this? 有没有可以解决此问题的解决方法?

Thanks. 谢谢。

The components are validated in the order as they are declared in the component tree. 组件按照在组件树中声明的顺序进行验证。

When you call UIInput#getValue() on a component which isn't validated yet, then it'll return null . 当您在尚未通过验证的组件上调用UIInput#getValue()时,它将返回null Also, when you call UIInput#getValue() on a component which is already validated and been marked invalid, then it'll return null (or the old model value). 另外,当您在已经验证并标记为无效的组件上调用UIInput#getValue()时,它将返回null (或旧模型值)。

If you want to get the value of the second component during validation of the first component, then you should be using UIInput#getSubmittedValue() instead of UIInput#getValue() . 如果要在验证第一个组件的过程中获取第二个组件的值,则应使用UIInput#getSubmittedValue()而不是UIInput#getValue() You should only keep in mind that this returns the unconverted String . 您只应记住,这将返回未转换的String

Alternatively, you could take a look at OmniFaces <o:validateAllOrNone> component. 另外,您可以查看OmniFaces <o:validateAllOrNone>组件。

<h:inputText id="city" value="#{search.city}" />
<h:inputText id="state" value="#{search.state}" />
<o:validateAllOrNone id="cityAndState" components="city state" message="Please fill both city and state." />
<h:message for="cityAndState" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM