2

以下の selectItems は、Session Scoped Map から供給されます。ユーザーが送信ボタンをクリックすると、Request Scoped バッキング Bean に日付フィールドが設定され、ページに表示されます。

    <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 コンバーターを設定しようとしましたが、さらに不可解な検証エラーが発生しました。

equal() メソッドが使用可能かどうか、および項目の選択がドロップダウンにあるかどうかを確認することを提案する投稿を見つけました。この場合、どちらも真である必要があります。

私が考えることができる 1 つの回避策は、日付が文字列として保存される場所で、キーが文字列になるようにマップを変更することです。しかし、それはやり過ぎのようです。

この設定を機能させる方法について何か提案はありますか?

バッキング 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;
    }
}

ありがとう!

4

1 に答える 1

5

日時コンバーターを使用することは正しい解決策であるはずです。あなたの「より不可解な検証エラー」はまさにこれであることが判明しました:

「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()、使用可能な日付のマップが偶然に生成されない限り、常に失敗します。ちょうど00:00:00.000真夜中。

この問題には 2 つの解決策があります。

  1. マッピングの日付の時間部分を削除します。これに使用できますjava.util.Calendar(または、Joda Time の方が適切です)。

  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>
    

    タイムゾーンとして GMT ではなくプラットフォーム固有のタイムゾーンを使用するように JSF を構成した場合は、タイムゾーンの問題に注意してください<f:convertDateTime>timeZone="UTC"次に、属性をコンバーターに明示的に追加します。

于 2012-12-27T15:41:54.690 に答える