【问题标题】:Validating three dependent h:selectOneMenus验证三个依赖 h:selectOneMenus
【发布时间】:2013-12-06 09:55:56
【问题描述】:

我想验证一个 jsf selectOne 菜单:

<h:selectOneMenu id="day" value="#{registerService.dayOfBirth}">
    <f:selectItems value="#{registerService.days}" />
    <f:validator validatorId="dateValidator" />
    <f:attribute name="monthId" value="#{component.parent.parent.clientId}:month" />
    <f:attribute name="yearId" value="#{component.parent.parent.clientId}:year" />
</h:selectOneMenu>

<h:selectOneMenu id="month" value="#{registerService.monthOfBirth}">
    <f:selectItems value="#{registerService.months}" />
</h:selectOneMenu>

<h:selectOneMenu id="year" value="#{registerService.yearOfBirth}">
    <f:selectItems value="#{registerService.years}" />
</h:selectOneMenu>

我的验证器是这样的:

@FacesValidator(value="dateValidator")
public class DateValidator implements Validator {

    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String year = (String) component.getAttributes().get("yearId");
        String month = (String) component.getAttributes().get("monthId");
        UIInput yearInput = (UIInput) context.getViewRoot().findComponent(year);
        UIInput monthInput = (UIInput) context.getViewRoot().findComponent(month);
        FacesMessage message = null;

        int yearValue = (Integer) yearInput.getValue();
        int monthValue = (Integer) monthInput.getValue();
        int dayValue = (Integer) value;

        Calendar calendar = Calendar.getInstance();
        calendar.set(yearValue, monthValue, dayValue);

        int daysOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        if (daysOfMonth < dayValue) {
            message = new FacesMessage ("Date is not valid!", "Email Validation Error");
            message.setDetail("This month does not have so many days!");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);

            throw new ValidatorException(message);
        }
    }
}

我收到此错误消息:

java.lang.IllegalArgumentException: j_idt12
at javax.faces.component.UIComponentBase.findComponent(UIComponentBase.java:655)
at de.hof.tschuwwa.controller.validators.DateValidator.validate(DateValidator.java:27)
at javax.faces.component.UIInput.validateValue(UIInput.java:1165)
at javax.faces.component.UISelectOne.validateValue(UISelectOne.java:146)
at javax.faces.component.UIInput.validate(UIInput.java:983)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1249)
at javax.faces.component.UIInput.processValidators(UIInput.java:712)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1261)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1261)
at javax.faces.component.UIForm.processValidators(UIForm.java:253)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:552)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1689)
at javax.faces.component.UIForm.visitTree(UIForm.java:371)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:399)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:263)
... 32 more

所以这里抛出异常:

UIInput yearInput = (UIInput) context.getViewRoot().findComponent(year);

我的其他验证器都在工作,但他们没有使用 selectOneMenu 与输入文本。

【问题讨论】:

    标签: validation jsf-2 selectonemenu


    【解决方案1】:

    您不能传递自动生成的 ID。给父命名容器组件一个固定的ID:

    <h:form id="myForm">
    

    或者,更好的是,只传递整个组件:

    <f:attribute name="month" value="#{month}" />
    <f:attribute name="year" value="#{year}" />
    ...
    <h:selectOneMenu binding="#{month}" ... />
    <h:selectOneMenu binding="#{year}" ... />
    

    并按如下方式获取它们:

    UIInput yearInput = (UIInput) component.getAttributes().get("year");
    UIInput monthInput = (UIInput) component.getAttributes().get("month");
    

    或者,更好的是,create a composite component based on the whole

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-27
      • 2012-04-03
      • 2013-09-12
      • 2012-10-28
      • 2010-12-28
      • 2016-05-27
      • 2011-04-27
      • 1970-01-01
      相关资源
      最近更新 更多