问题描述
以下代码创建了两个单选按钮.每个选项都包含一个成功转换为yyyy-MM-dd"格式标签的日期值.一旦我做出选择并单击下一步按钮,我就会收到以下错误j_idt12:comDateChoice: Validation Error: Value is not valid".这看起来很简单,但有些不对劲.你们有人能看出来吗?
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?
我在 glassfish 中使用 JSF 2.0.
I'm using JSF 2.0 in glassfish.
支持豆
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>
推荐答案
如果所选项目值没有通过任何可用选择的 Object#equals()
检查,则会发生此错误项值.如果 getter 在表单提交请求的应用请求值阶段返回的列表与在显示表单的初始请求期间返回的列表不同,就会发生这种情况.
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.
因为您是在 getter 中重建列表而不是在视图作用域 bean 的构造函数中构造一次,所以 Date
对象在每次调用时都会获得不同的时间戳,这将是几分钟/seconds 与初始 Date
对象相比.因此 equals()
将失败.
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 initial Date
objects. Hence the equals()
will fail.
将此逻辑移动到 bean 的构造函数中并重写 getter,以便它执行它应该做的事情:只返回数据.不要在 getter 中做加载逻辑.您还应该将 bean 放在视图范围内,以便在您提交表单时构造函数不会重新运行.
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.
@ManagedBean
@ViewScoped
public class SignUpBean {
private List<SelectItem> comDateList;
public SignUpBean() {
comDateList = new ArrayList<SelectItem>();
// Fill it here.
}
public List<SelectItem> getComDateList() {
return comDateList; // In getters, do nothing else than returning data!
}
}
更新:转换器也是问题的潜在来源.您基本上已经指示它在呈现 HTML 页面时去除时间.所以它在转换回 Date
时使用默认时间.要么使用
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 use
<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS Z" />
或预先在Calendar
上重置时间和时区:
or reset the time and timezone on the Calendar
beforehand:
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
这样你就可以只使用 <f:convertDateTime type="date"/>
这篇关于“验证错误:值无效"来自 f:datetimeConverter 的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!