JSF 2 - f:带有Date键控Map的selectItems [英] JSF 2 - f:selectItems with a Date keyed Map

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

问题描述

以下selectItems来自Session Scoped Map。当用户单击Submit按钮时,它应该在Request Scoped支持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()方法是否可用,以及项目选择是否在下拉列表中,在这种情况下两者都应为true。

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.

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

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;
    }

}

地图bean:

@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:


这是form:location:Validation Error:Value无效

Object#equals()对于任何可用项目,所选项目的测试未返回 true 。因此,所选日期与任何可用的日期实例都不匹配。

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.

实际上,转换器= javax.faces.DateTime(又名< f:convertDateTime /> )默认忽略时间部分。默认打印时短期日期样式,如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将该格式的字符串提交值转换回具体的时日期实例,它基本上变成 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.

此问题有2个解决方案:

There are 2 solutions for this problem:


  1. 删除映射中日期的时间部分。您可以使用 java.util.Calendar 来实现此目的(或更好的Joda时间)。

  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时,请注意时区问题code>< f:convertDateTime> 时区。您想明确地将 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:带有Date键控Map的selectItems的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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