JSF 2 - 带有日期键映射的 f:selectItems [英] JSF 2 - f:selectItems with a Date keyed Map

查看:19
本文介绍了JSF 2 - 带有日期键映射的 f:selectItems的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的 selectItems 来自会话范围映射.当用户单击提交按钮时,应该在请求范围的支持 bean 中设置一个日期字段并将其显示在页面上.

The below selectItems is fed from a Session Scoped Map. When the user clicks the Submit button, it is supposed to set a date field in the Request Scoped backing bean and display it on the page.

    <h:selectOneMenu value="#{dropDown.selectedDate}">
        <f:selectItems value="#{mapValues.dateMap.entrySet()}" var="entry" itemLabel="#{entry.value}" itemValue="#{entry.key}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" />
You selected Date #{dropDown.selectedDate}

但是,收到以下转换错误:

However, the following conversion error is received:

Conversion Error setting value 'Wed Dec 26 15:09:32 EST 2012' for 'null Converter'. 

我不确定为什么会收到此错误.我尝试在 selectOneMenu 标记上设置 javax.faces.DateTime 转换器,但随后收到了一个更加神秘的验证错误.

I'm not sure why this error is received. I attempted setting a javax.faces.DateTime converter on the selectOneMenu tag, but then received an even more cryptic validation error.

发现 一篇帖子,建议检查 equal() 方法是否有效可用,并且项目选择在下拉列表中,在这种情况下这两者都应该是真的.

Found a post that suggests checking if the equal() method is available, and that the item select is in the dropdown, both of which should be true in this case.

我能想到的一种解决方法是将我的地图更改为字符串键控,其中日期保存为字符串.但这似乎有点矫枉过正.

One workaround I can think of is to change my map to be String keyed where dates are saved off as strings. But it seems like an overkill.

关于如何让这个设置工作有什么建议吗?

Any suggestions on how to get this set up to work?

支持bean:

@Named
@RequestScoped
public class DropDown {

    private Date selectedDate;

    public Date getSelectedDate() {
        return selectedDate;
    }

    public void setSelectedDate(Date selectedDate) {
        this.selectedDate = selectedDate;
    }

}

映射豆:

@Named
@SessionScoped
public class MapValues implements Serializable {

    private Map<Date, String> dateMap;

    @PostConstruct
    public void init() {        
        dateMap = new LinkedHashMap<Date, String>();
        dateMap.put(new Date(), "DATEVALUE1");      
    }

    public Map<Date, String> getDateMap() {
        return dateMap;
    }

    public void setDateMap(Map<Date, String> dateMap) {
        this.dateMap = dateMap;
    }
}

谢谢!

推荐答案

使用日期时间转换器应该是正确的解决方案.你的更神秘的验证错误"原来是这样的:

Using the date time converter should have been the right solution. Your "more cryptic validation error" turns out to be just this:

它是表单:位置:验证错误:值无效

当所选项目的 Object#equals() 测试没有为任何可用项目返回 true 时,就会发生这种情况.因此,所选的 Date 与任何可用的 Date 实例都不匹配.

This will occur when the Object#equals() test of the selected item has not returned true for any of the available items. So, the selected Date did not match any of the available Date instances.

事实上,converter="javax.faces.DateTime"(又名 )默认忽略时间部分.它默认打印短"日期样式,如2012 年 12 月 27 日"在浏览器中右键单击页面,选择查看源自己查看.

And indeed, the converter="javax.faces.DateTime" (aka <f:convertDateTime />) ignores by default the time part. It prints by default the "short" date style like "Dec 27, 2012" Rightclick page in browser, choose View Source to see it yourself.

<option value="Dec 27, 2012">DATEVALUE1</option>

当 JSF 将这种格式的字符串提交值转换回具体的 Date 实例时,它基本上变成了 2012-12-27 00:00:00.000 而日期您的地图中提供的显然时间部分仍然设置,导致 equals() 总是失败,除非可用日期的地图恰好在 00:00:00.000> 午夜.

When JSF converts the string submitted value in that format back to a concrete Date instance, it becomes basically 2012-12-27 00:00:00.000 while the dates provided in your map have apparently the time part still set, causing the equals() to always fail unless the map of available dates is by coincidence generated at exactly 00:00:00.000 midnight.

这个问题有两种解决方案:

There are 2 solutions for this problem:

  1. 删除映射中日期的时间部分.为此,您可以使用 java.util.Calendar(或更好的 Joda Time).

  1. Remove the time part of the dates in your mapping. You can use java.util.Calendar for this (or better, Joda Time).

改用 <f:convertDateTime pattern="yyyyMMddHHmmssSSS"/> 将整个日期/时间转换为最后一毫秒.

Use <f:convertDateTime pattern="yyyyMMddHHmmssSSS"/> instead to convert the entire date/time up to with the last milli second.

<h:selectOneMenu value="#{dropDown.selectedDate}">
    <f:selectItems value="#{mapValues.dateMap.entrySet()}" var="entry" itemLabel="#{entry.value}" itemValue="#{entry.key}" />
    <f:convertDateTime pattern="yyyyMMddHHmmssSSS" />
</h:selectOneMenu>

这样选项值就变成了

<option value="20121227114627792">DATEVALUE1</option>

当您将 JSF 配置为使用平台特定时区而不是 GMT 作为 时区时,请注意时区问题.然后您想显式地将 timeZone="UTC" 属性添加到转换器.

Be careful with timezone issues when you've configured JSF to use platform specific timezone instead of GMT as <f:convertDateTime> timezone. You'd like to explicitly add timeZone="UTC" attribute to the converter then.

这篇关于JSF 2 - 带有日期键映射的 f:selectItems的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆