rich:日历本机验证隐藏/覆盖/ ??我的bean验证错误

时间:2012-03-13 19:46:08

标签: jsf-2 richfaces

我的应用程序使用rich:calendars和h:inputText。如果我在UI中为intputText(即非数字数据)输入错误数据并按“搜索”,我会从bean中获取正确的错误消息。但是,如果我在inputText(非数字)和rich:calendar(非日期相关输入,如“foo”)中输入无效数据,我只会返回rich:calendar错误消息。就好像本机富日历验证消息会敲除bean验证消息。

如何显示所有消息?

xhtml代码如下:

    <html xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:tr="http://myfaces.apache.org/trinidad"
      xmlns:rich="http://richfaces.org/rich">
<f:view>
    <br/>
    <div class="container">
    <tr:form id="searchCriteria" defaultCommand="appealSearchManager.search">
        <a4j:outputPanel id="errorMessagesPanel">
            <h:messages id="errorMessages"/>
        </a4j:outputPanel>
        <div class="div30">
            <p><h:outputText value="#{messages.ProgramInvoiceId}"/></p>
            <h:inputText id="programInvoiceId" value="#{appealSearchManager.programInvoiceId}"/>
        </div>
        <div class="div30">
        <p><h:outputText value="#{messages.ResponseReleaseDate}"/></p>
        <rich:calendar id="responseReleaseDateBegin"
            enableManualInput="true"  datePattern="MM/dd/yyyy"
            buttonIcon="/images/calendar_icon.jpg" buttonClass="calendar"
            converterMessage="Invalid Response Release begin date.  Format must be blah, blah, blah."
            value="#{appealSearchManager.responseReleaseDateBegin}">
        </rich:calendar>
        <rich:calendar id="responseReleaseDateEnd"
            enableManualInput="true"  datePattern="MM/dd/yyyy"
            buttonIcon="/images/calendar_icon.jpg" buttonClass="calendar"
           converterMessage="Invalid Response Release End date.  Format must be blah, blah, blah."
            value="#{appealSearchManager.responseReleaseDateEnd}">
        </rich:calendar>
        </div>

        <div class="searchaction">
            <div>
                <ul>

                    <li>
                        <a4j:commandLink id="searchButton"
                                         value="#{messages.Search}"
                                         actionListener="#{appealSearchManager.search}"
                                         reRender="errorMessagesPanel, richErrorMessages, errorMessages"
                                         styleClass="searchbtn"/>
                    </li>
                </ul>
            </div>
        </div>
    </tr:form>
    </div>
</f:view>
</html>

和bean代码:

    public void search(ActionEvent e) {
    setHasErrors(validateCriteria());
}

private boolean validateCriteria() {
    boolean isValid = true;
    //always check for Program Invoice ID may contain a comma-separated list of ids
    if (getProgramInvoiceId() != null && !getProgramInvoiceId().equals("") && !areValidProgamInvoiceIds(getProgramInvoiceId())) {
        String errorMessage = "Invalid Program Invoice ID.  Must be comma delimited list of numbers.";
        FacesContext.getCurrentInstance().addMessage(null,
                                                     new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, errorMessage));
        isValid = false;
    }
    //check Dates Response Release Date
    if (!isValidDateRange("Response Release Date", getResponseReleaseDateBegin(), getResponseReleaseDateEnd())) {
        isValid = false;
    }
    return isValid;
}

private boolean areValidProgamInvoiceIds(String ids) {
    boolean validIds = true;
    String regexp = "^([0-9]+(-[0-9]+)*,*)+$";
    Pattern pattern = Pattern.compile(regexp);
    if (!pattern.matcher(ids).matches()) {
        validIds = false;
    }
    return validIds;
}

private boolean isValidDateRange(String dateRange, Date startDate, Date endDate) {
    boolean isValidDateAndRange = true;
    Calendar futureDate = Calendar.getInstance();
    futureDate.roll(Calendar.DAY_OF_MONTH, 2);
    if ((startDate != null && (endDate == null || endDate.equals(""))) ||
         ((startDate == null || startDate.equals("")) && endDate != null)) {
        //one date is null and the other has a value.  We need both values to do a search.
        String errorMessage = "Invalid " + dateRange + " range.  Missing Date. A date range must contain both start and end dates.";
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, errorMessage));
    } else if (startDate != null && endDate != null) {
        if (isValidDateAndRange) {
            //future start dates are not allowed
            if (startDate.after(futureDate.getTime())) {
                String errorMessage = "Invalid date range.  Start date must be less than today's date.";
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, errorMessage));
                isValidDateAndRange = false;
            }
            //start date greater than the end date is not allowed
            if (endDate.before(startDate)) {
                String errorMessage = "Invalid date range.  End date must be greater than or equal to start date.";
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, errorMessage));
                isValidDateAndRange = false;
            }
        }
    }
    return isValidDateAndRange;
}

任何建议都将不胜感激。 谢谢!

1 个答案:

答案 0 :(得分:0)

您不应在操作方法内执行验证。您应该使用Validator或任何标准<f:validator>标记绑定的普通<f:validateXxx>来执行此操作。验证失败时,永远不会调用action方法。

例如,要验证计划发票ID,请使用<f:validateRegex>

<h:inputText id="programInvoiceId" value="#{appealSearchManager.programInvoiceId}" validatorMessage="Invalid Program Invoice ID.  Must be comma delimited list of numbers.">
    <f:validateRegex pattern="^([0-9]+(-[0-9]+)*,*)+$" />
</h:inputText>

验证日期范围有点复杂。至此,您需要将Validator类作为<f:validator>放在其中一个组件上,并将另一个组件的值作为属性传递。有关示例,另请参阅Compare two fields that use same class

顺便说一下,要小心使用术语,您完全使用"bean validation" ,但您只需在操作方法中手动验证。