“验证错误:值无效”来自 f:datetimeConverter 的错误

发布于 2024-10-25 01:28:35 字数 1342 浏览 1 评论 0原文

以下代码创建两个单选按钮。每个选项都包含一个已成功转换为“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情愿 2024-11-01 01:28:35

如果所选项目值未通过对任何可用选择项目值的 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"));

这样您就可以只使用

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 initial Date objects. Hence the equals() 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.

@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!
    }

}

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" />

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

this way you can use just a <f:convertDateTime type="date" />

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文