我有一个带有两个日期输入字段的表单。第一个名为dateFrom的字段总是在页面重新加载时失去它的值,而第二个名为dateTo的字段工作得很好。当我填充这两个字段时,这两个值都传递给UI Bean,并且都成功地用于过滤视图(项列表)。UI Bean将这两个值存储在具有会话作用域的statusObject中。
但是在页面更新之后,只有dateTo仍然被填充,而dateFrom一个是空的。我在这些值的getter和set中添加了一些System.out.println()
,看看会发生什么,两个setter都带着一个值被调用,然后两个getter都返回一个值。dateFrom字段只是忽略它从UI Bean获得的值。
我使用浏览器提供的日期字段,因此使用a:type="date"
页面是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:a="http://xmlns.jcp.org/jsf/passthrough"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head/>
<h:body>
<ui:composition>
<f:loadBundle basename="de.myapp.Resources" var="bundle"/>
<!-- Some stuff removed for readability -->
<h:form enctype="multipart/form-data" id="filterForm">
<div class="filterBar">
<div class="filterElement">
<h:inputText a:type="date" id="dateFrom" size="8" maxlength="10"
value="#{myBean.dateFrom}"
converter="dateConverter"/>
</div>
<div class="filterElement">
<h:inputText a:type="date" id="dateTo" size="8" maxlength="10"
value="#{myBean.dateTo}"
converter="dateConverter"/>
</div>
</div>
<div class="filterElement">
<h:commandButton id="refreshButton"
action="#{myBean.refreshList}"
value=" #{bundle.refresh}"/>
</div>
</h:form>
<!-- Some more stuff removed for readability -->
</ui:composition>
</body>
</html>
我已经检查了dateFrom和dateTodonot出现在我删除的部分
UI Bean中的getter和setter
public Date getDateFrom() {
System.out.println("getDateFrom() -> " + statusObjet.getDateFrom());
return statusObjet.getDateFrom();
}
public void setDateFrom(final Date dateFrom) {
if (dateFrom != null) {
System.out.println("setDateFrom( " + dateFrom + " )");
} else {
System.err.println("setDateFrom( NULL )"); // my IDE shows this colored red in the console
}
statusObjet.setDateFrom(dateFrom);
}
public Date getDateTo() {
System.out.println("getDateTo() -> " + statusObjet.getDateTo());
return statusObjet.getDateTo();
}
public void setDateTo(final Date dateTo) {
if (dateTo != null) {
System.out.println("setDateTo( " + dateTo + " )");
} else {
System.err.println("setDateTo( NULL )"); // my IDE shows this colored red in the console
}
statusObjet.setDateTo(dateTo);
}
除了ID和值EL外,两个字段完全相同。getter和setter也是相同的(我已经仔细检查过了)。实际上,dateTo的所有代码都是dateFrom的副本,在复制后在编辑器中进行了更改(在选择中替换所有代码)。
为什么dateTo可以,而dateFrom不行?
问题不在于日期字段,而在于输入的日期(以及dateConverter中的一个缺陷):
我一直使用Jan 1st和Dec 31同年的测试表单。
知道浏览器提供的日期输入使用的日期格式取决于浏览器语言而不是网站语言,我编写了一个dateConverter,它可以理解最重要的格式,所有这些格式都有或没有一位数值的前导零。
这个缺陷是getAsString()
返回一个没有前导零的日期格式,并且浏览器不理解例如2019-1-1.
解决方案:使用单独的DateFormat强制getAsString()
的前导零并返回2019-01-01。