1

フォーミュラーとドロップダウンメニューを備えたフェイスレットページが必要です。ドロップダウン メニューを使用して、ユーザーは Lieferant タイプの POJO を選択する必要があります。

public class Lieferant extends AbstractPersistentWarenwirtschaftsObject {

    private String firma;

    public Lieferant(WarenwirtschaftDatabaseLayer database, String firma) {
        this(database, null, firma);
    }

    public Lieferant(WarenwirtschaftDatabaseLayer database, Long primaryKey, String firma) {
        super(database, primaryKey);
        this.firma = firma;
    }

    public String getFirma() {
        return firma;
    }

    @Override
    public String toString() {
        return getFirma();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((firma == null) ? 0 : firma.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Lieferant other = (Lieferant) obj;
        if (firma == null) {
            if (other.firma != null)
                return false;
        } else if (!firma.equals(other.firma))
            return false;
        return true;
    }

}

私が書いたfaceletコードは次のとおりです。

<h:selectOneMenu> 

鬼ごっこ。このタグは、タイプ Lieferant の POJO (Bean ではない) のリストを表示する必要があります。フェイスレットのコードは次のとおりです。

<h:selectOneMenu id="lieferant" value="#{lieferantenBestellungBackingBean.lieferant}">
 <f:selectItems var="lieferant" value="#{lieferantenBackingBean.lieferanten}" itemLabel="#{lieferant.firma}" itemValue="#{lieferant.primaryKey}" />
 <f:converter converterId="LieferantConverter" />
</h:selectOneMenu>

参照されたマネージド バッキング Bean は次のとおりです。

@ManagedBean
@RequestScoped
public class LieferantenBackingBean extends AbstractWarenwirtschaftsBackingBean {

    private List<Lieferant> lieferanten;

    public List<Lieferant> getLieferanten() {
        if (lieferanten == null) {
            lieferanten = getApplication().getLieferanten();
        }
        return lieferanten;
    }

}

私の知る限り、Lieferant オブジェクトの POJO 表現と String 表現を交換するには、カスタム コンバーターが必要です。コンバーターは次のようになります。

@FacesConverter(value="LieferantConverter")
public class LieferantConverter implements Converter {

 @Override
 public Object getAsObject(FacesContext context, UIComponent component, String value) {
  long primaryKey = Long.parseLong(value);
  WarenwirtschaftApplicationLayer application = WarenwirtschaftApplication.getInstance();
  Lieferant lieferant = application.getLieferant(primaryKey);
  return lieferant;
 }

 @Override
 public String getAsString(FacesContext context, UIComponent component, Object value) {
  return value.toString();
 }

}

ページはエラーなしで読み込まれます。Formular に入力して送信すると、ページに次のエラー メッセージが表示されます。

Bestellung:lieferantenBestellungForm:lieferant: Validierungsfehler: Wert ist keine gültige Auswahl
translated: validation error: value is not a valid selection

残念ながら、それがどの値について話しているかはわかりません。コンバーターは正常に動作しているようです。

stackoverflowと this article about selectOneMenu and convertersからこの同様の質問を見つけましたが、コードで問題を見つけることができませんでした。なぜですか

List<SelectItem> 

2番目のリンクの例で使用されています。私にも同じエラーが発生します。

どんな助けでも大歓迎です。前もって感謝します。

4

2 に答える 2

2

検証エラー: 値は有効な選択ではありません

このエラーは、選択されたアイテムがリスト内のどの選択アイテムとも一致しないことを意味します。あなたの場合、これには2つの原因が考えられます.Object#equals()実装が間違っているか<f:selectItems>、最初のリクエスト時(フォームの送信前、選択中)と同じように、背後のゲッターが(フォームの送信中に)後続のリクエストで同じリストを返しません値)。

いずれかを除外するにはObject#equals()、「プレーン バニラ」テストケースで簡単にテストでき、Bean をセッション スコープに置くことでリストの一貫性をテストできます。

明確にするために、コンバーターは正常に動作しているように見えます (そうでなければ、この種のエラー メッセージを受け取ることはできません。変換ステップは正常に完了しました)。

于 2010-03-23T15:52:50.703 に答える
0

コンバーターが正しく動作していることは確かでしたが、最終的なエラーはコンバーターにありました。おそらく、これは何時間ものデバッグ中に発生した可能性があります。これは、コンバーターの固定 getAsString メソッドです。N

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value != null && value instanceof Lieferant) {
        Lieferant lieferant = (Lieferant) value;
        return "" + lieferant.getPrimaryKey();
    }
    return "";
}

これで、selectOneMenu リストの値として使用される primaryKey が返されます。さらに、selectItems タグからこの属性を変更しました。

 itemValue="#{lieferant}"

この最後の変更が必要であったかどうか、今のところ確信が持てません。しかし、今ではリーフェラントは正しく変換されています。

于 2010-03-23T16:32:29.550 に答える