“验证错误:值无效”来自 f:datetimeConverter 的错误
以下代码创建两个单选按钮。每个选项都包含一个已成功转换为“yyyy-MM-dd”格式的标签的日期值。一旦我做出选择并单击下一步按钮,我会收到以下错误“j_idt12:comDateChoice:验证错误:值无效”。这看起来很简单,但有些问题。你们谁能发现它吗?
我在 glassfish 中使用 JSF 2.0。
支持 bean
public List<SelectItem> getComDateList() {
List<SelectItem> items = new ArrayList<SelectItem>();
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.MONTH, 1);
Date nextFirst = cal.getTime();
cal.add(Calendar.MONTH, 1);
Date followingFirst = cal.getTime();
items.add(new SelectItem(nextFirst, new SimpleDateFormat("yyyy-MM-dd").format(nextFirst)));
items.add(new SelectItem(followingFirst, new SimpleDateFormat("yyyy-MM-dd").format(followingFirst)));
return items;
}
JSF 代码
<h:panelGrid columns="2">
<h:outputLabel value="#{msg.FinanceCommencementDate}" for="comDateChoice"/>
<h:selectOneRadio id="comDateChoice" value="#{signUpBean.current.commencementDate}" layout="pageDirection">
<f:convertDateTime type="date" dateStyle="short"/>
<f:selectItems value="#{signUpBean.comDateList}"/>
</h:selectOneRadio>
</h:panelGrid>
The following code creates a two radio buttons. Each option contains a date value that is successfully converted to a label of the format "yyyy-MM-dd". Once I make a selection and click the next button I get the following error "j_idt12:comDateChoice: Validation Error: Value is not valid". It seems simple enough but somethings wrong. Can any of you spot it?
I'm using JSF 2.0 in glassfish.
Backing bean
public List<SelectItem> getComDateList() {
List<SelectItem> items = new ArrayList<SelectItem>();
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.MONTH, 1);
Date nextFirst = cal.getTime();
cal.add(Calendar.MONTH, 1);
Date followingFirst = cal.getTime();
items.add(new SelectItem(nextFirst, new SimpleDateFormat("yyyy-MM-dd").format(nextFirst)));
items.add(new SelectItem(followingFirst, new SimpleDateFormat("yyyy-MM-dd").format(followingFirst)));
return items;
}
JSF Code
<h:panelGrid columns="2">
<h:outputLabel value="#{msg.FinanceCommencementDate}" for="comDateChoice"/>
<h:selectOneRadio id="comDateChoice" value="#{signUpBean.current.commencementDate}" layout="pageDirection">
<f:convertDateTime type="date" dateStyle="short"/>
<f:selectItems value="#{signUpBean.comDateList}"/>
</h:selectOneRadio>
</h:panelGrid>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果所选项目值未通过对任何可用选择项目值的
Object#equals()
检查,则会出现此错误。如果 getter 在表单提交请求的应用请求值阶段返回的列表与显示表单的初始请求期间返回的列表不同,则可能会发生这种情况。因为您在 getter 中重建列表,而不是在视图作用域 bean 的构造函数中构造一次,所以
Date
对象将在每次调用时获得不同的时间戳,这将是一些分钟/秒与初始Date
对象相比的未来。因此equals()
将失败。将此逻辑移至 bean 的构造函数中并重写 getter,以便它执行其应该执行的操作:仅返回数据。不要在 getter 中执行加载逻辑。您还应该将该 bean 放入视图范围中,以便在您提交表单时构造函数不会重新运行。
更新:转换器也是问题的潜在根源。您基本上已指示它缩短渲染 HTML 页面的时间。因此,它在转换回
Date
时使用默认时间。 事先使用或重置
Calendar
上的时间和时区:这样您就可以只使用
This error will occur if the selected item value didn't pass the
Object#equals()
check on any of the available select item values. This can happen if the getter returned a different list during the apply request values phase of the form submit request than it did during the initial request to display the form.Because you're reconstructing the list in the getter instead of constructing once in the constructor of a view scoped bean, the
Date
objects will get a different timestamp on every call, it will be some minutes/seconds in the future as compared to the initialDate
objects. Hence theequals()
will fail.Move this logic into the constructor of the bean and rewrite the getter so that it does what it is supposed to do: return only the data. Do not do loading logic in a getter. You should also put the bean in the view scope so that the constructor doesn't re-run when you submit the form.
Update: the converter is also a potential source of the problem. You've basically instructed it to strip off the time when rendering the HTML page. So it uses the default time when converting back to
Date
. Either useor reset the time and timezone on the
Calendar
beforehand:this way you can use just a
<f:convertDateTime type="date" />