【问题标题】:"Validation Error: Value is not valid" error from f:datetimeConverter来自 f:datetimeConverter 的“验证错误:值无效”错误
【发布时间】:2011-07-21 08:56:18
【问题描述】:

以下代码创建了两个单选按钮。每个选项都包含一个日期值,该日期值已成功转换为“yyyy-MM-dd”格式的标签。一旦我做出选择并单击下一步按钮,我会收到以下错误“j_idt12:comDateChoice:验证错误:值无效”。这似乎很简单,但有些不对劲。你们有人能发现吗?

我在 glassfish 中使用 JSF 2.0。

支持豆

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>

【问题讨论】:

  • 你的signUpBean.current.commencementDate是什么类型的?

标签: validation date jsf jsf-2 selectoneradio


【解决方案1】:

如果所选项目值未通过对任何可用选择项目值的Object#equals() 检查,则会发生此错误。如果 getter 在表单提交请求的应用请求值阶段返回的列表与在显示表单的初始请求期间返回的列表不同,就会发生这种情况。

因为您是在 getter 中重建列表,而不是在视图范围 bean 的构造函数中构造一次,所以 Date 对象在每次调用时都会获得不同的时间戳,它将在未来几分钟/几秒与最初的 Date 对象相比。因此equals() 将失败。

将此逻辑移到 bean 的构造函数中并重写 getter,以便它完成它应该做的事情:只返回数据。不要在 getter 中执行加载逻辑。您还应该将 bean 放在视图范围内,以便在您提交表单时构造函数不会重新运行。

@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 时使用默认时间。要么使用

<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS Z" />

或事先在Calendar 上重置时间和时区:

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"));

这样你就可以只使用&lt;f:convertDateTime type="date" /&gt;

【讨论】:

  • 我将不得不阅读这个......所以我应该制作一个单独的 bean @ViewScoped 并保存这个模型的列表和任何其他需要访问的数据我的此页面上的视图?
  • 不,你可以使用同一个bean。您只需将 getter 中的逻辑移动到构造函数中并标记 bean @ViewScoped(如果它是 @RequestScoped)。我用一个启动示例更新了答案。
  • 谢谢,我已将代码转换为类似于您的示例的 ne。 bean 是@SessionScoped,所以我就这样离开了。但错误仍然存​​在。
  • 我创建了一个全新的项目来使用您上面的框架进行测试。转换器不仅不改变文本,它仍然有同样的错误。当我不包含它时,它会给出一个空转换器错误,因此转换器不会被完全忽略。我已经得出结论,这可能是一个错误或其他东西,我只是使用字符串表示,因为我没有时间再处理这个了。感谢您的输入。我从中学到了一些东西。
  • 我在本地进行了测试,默认转换不包括微秒,因此验证失败(这意味着我之前的评论无效,对此感到抱歉)。我将其更改为包含每个部分的固定模式并且它可以工作:&lt;f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS Z" /&gt;。另一方面,您还可以将 Calendar 对象上的小时/分钟/秒/毫秒归零,因为它们与您无关。
猜你喜欢
  • 1970-01-01
  • 2015-11-03
相关资源
最近更新 更多