0

ページに次のドロップダウンボックスを定義しました:..。

<td>
  <h:selectOneMenu id="bootenvironment1" value="#{detailModel.selectedBootenvironment1}"
                   disabled="#{detailModel.mode == detailModel.viewMode}">
    <f:selectItems value="#{detailModel.availableBootenvironments}"/>
  </h:selectOneMenu>
</td>

私のモデルでは:

...
  private Map<String, Bootenvironment> availableBootenvironments;

  public DefinitionDetailModel()
  {
    super();
  }

  public String getSelectedBootenvironment1()
  {
    if (((Definition) getAfterObject()).getBootenvironment1() != null)
    {
      return ((Definition) getAfterObject()).getBootenvironment1().getEnvironmentName();
    }

    return "--Please select one--";
  }

  public void setSelectedBootenvironment1( String selectedBootenvironment )
  {
    ((Definition) getAfterObject()).setBootenvironment1(availableBootenvironments.get(selectedBootenvironment));
  }
  ...

そして、コントローラーで、availableBootenvironmentsマップを設定しました。

private void fetchBootenvironments()
  {
    ...
    @SuppressWarnings( "unchecked" )
    List<Bootenvironment> bootenvironments = (List<Bootenvironment>) ...

    Map<String, Bootenvironment> availableBootenvironments = new HashMap<String, Bootenvironment>();

    availableBootenvironments.put("--Please select one--", null);

    for(Bootenvironment bootenvironment : bootenvironments)
    {
      availableBootenvironments.put(bootenvironment.getEnvironmentName(), bootenvironment);
    }

    ((DefinitionDetailModel) detailModel).setAvailableBootenvironments(availableBootenvironments);
  }

問題は、ページ内のボタン(アクションにバインドされている)をクリックすると、次のエラーが発生することです。

detailForm:bootenvironment1:検証エラー:値が無効です。

エラーがどこにあるのかわかりません。selectItemsは、オブジェクトの名前フィールド(つまり文字列)をキーとして、オブジェクト自体を値として持つマップです。次に、モデルのgetter / setterメソッドでわかるように、デフォルトで選択された( )の値も文字列です。value="#{detailModel.selectedBootenvironment1}"

もう1つの問題(前の問題に関連している可能性があります)は、ページが最初に読み込まれるときに、 getBootenvironment1()がnullを返すため、デフォルトで選択された値が--いずれかを選択してください---である必要があることですが、これは発生しません。リストが選択されています。

私が何を/どこで間違っているのかを理解するのを手伝ってくれませんか?

編集

あなたが言ったように私はコンバーターを実装しました:

@FacesConverter( forClass = Bootenvironment.class )
public class BootenvironmentConverter implements Converter
{

  @Override
  public String getAsString( FacesContext context, UIComponent component, Object modelValue ) throws ConverterException
  {
    return String.valueOf(((Bootenvironment) modelValue).getDbId());
  }

  @Override
  public Object getAsObject( FacesContext context, UIComponent component, String submittedValue ) throws ConverterException
  {
    List<Bootenvironment> bootenvironments = ... (get from DB where dbid=submittedValue)

    return bootenvironments.get(0);
  }

}

しかし、今、私は次のエラーがあります:

java.lang.ClassCastException:java.lang.Stringをch.ethz.id.wai.bootrobot.bo.Bootenvironmentにキャストできません

4

1 に答える 1

2

equals()選択したアイテム値が使用可能なアイテム値のいずれのテストにも合格しない場合、このエラーが発生します。

実際、Bootenvironmentアイテム値のリストはありますが、プロパティをにバインドしました。これは、送信された値として渡される値にString依存しており、通常のJSFをまったく使用していないことを示します。Aは、オブジェクトを使用したテストに戻ることはできません。Bootenvironment#toString()ConverterStringtrueequals()Bootenvironment

とその一意の表現Converterの間で変換するを提供する必要があります。通常、技術ID(データベースから自動生成されたPKなど)が一意の表現として使用されます。BootenvironmentStringString

@FacesConverter(forClass=Bootenvironment.class)
public class BootenvironmentConverter implements Converter {

    @Override
    public void getAsString(FacesContext context, UIComponent component, Object modelValue) throws ConverterException {
        // Write code to convert Bootenvironment to its unique String representation. E.g.
        return String.valueOf(((Bootenvironment) modelValue).getId());
    }

    @Override 
    public void getAsObject(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
        // Write code to convert unique String representation of Bootenvironment to concrete Bootenvironment. E.g.
        return someBootenvironmentService.find(Long.valueOf(submittedValue));
    }

}

selectedBootenvironment1最後に、それに応じてコンバーターを実装した後、ゲッター/セッターを混乱させることなく、プロパティを通常のプロパティに修正できるはずです。

private Bootenvironment selectedBootenvironment1;

public Bootenvironment getSelectedBootenvironment1() {
    return selectedBootenvironment1;
}

public void setSelectedBootenvironment1(Bootenvironment selectedBootenvironment1) {
    this.selectedBootenvironment1 = selectedBootenvironment1;
}
于 2012-10-30T16:32:21.227 に答える