验证三个依赖的h:selectOneMenus

时间:2013-11-21 18:38:11

标签: validation jsf-2 selectonemenu

我想验证一个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不同 与inputText。

1 个答案:

答案 0 :(得分:0)

您无法传递自动生成的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