2012-12-26 28 views
2

以下selectItems是從會話作用域映射饋送的。當用戶點擊Submit按鈕時,應該在Request Scoped後備bean中設置一個日期字段並將其顯示在頁面上。JSF 2 - f:使用日期鍵控的selectItems地圖

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

但是,收到以下轉換錯誤:

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

我不知道爲什麼會收到此錯誤。我試圖在selectOneMenu標籤上設置一個javax.faces.DateTime轉換器,但後來又收到了一個更加神祕的驗證錯誤。

找到a post,建議檢查equal()方法是否可用,以及item select是否在下拉列表中,在這種情況下兩者都應該爲true。

我能想到的一種解決方法是將我的地圖更改爲字符串鍵,其中日期以字符串形式保存。但它似乎是一個過度殺傷力。

關於如何讓這套設置起作用的任何建議?

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

謝謝!

+0

*「但後來收到了一個更加神祕的驗證錯誤。」*你爲什麼不在你的問題中講述它? – BalusC

+0

這是「窗體:位置:驗證錯誤:值無效」 –

回答

5

使用日期時間轉換器應該是正確的解決方案。你「更神祕的驗證錯誤」原來是隻此:

It was "form:location: Validation Error: Value is not valid

當所選項目的Object#equals()測試任何可用的項目還沒有回來true這會發生。因此,所選的Date與任何可用的Date實例都不匹配。

實際上,converter="javax.faces.DateTime"(又名<f:convertDateTime />)默認忽略時間部分。它默認打印「短」日期樣式,如「2012年12月27日」右鍵點擊瀏覽器頁面,選擇查看源代碼自己查看。

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

當JSF轉換該格式提交的值回具體Date實例的字符串,它成爲基本2012-12-27 00:00:00.000而在你的地圖提供的日期有明顯的時間部分仍設置,導致equals()總是失敗,除非可用日期的地圖恰好在午夜處產生。

有此問題的2個解決方案:

  1. 刪除在映射中的日期時間的一部分。你可以使用java.util.Calendar這個(或更好的,喬達時間)。

  2. 改爲使用<f:convertDateTime pattern="yyyyMMddHHmmssSSS"/>將整個日期/時間轉換爲最後一毫秒。

    <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時區<f:convertDateTime>。您希望明確地將timeZone="UTC"屬性添加到轉換器。

+0

第二種解決方案的確有用。感謝您的詳細解釋! –

+0

不客氣。 – BalusC