我的应用程序使用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;
}
任何建议都将不胜感激。 谢谢!
答案 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" ,但您只需在操作方法中手动验证。