6

xhtmlビューをサポートするビュースコープのJSF管理対象Beanがあり、 f:viewParamを使用してURLから1つのパラメーターを読み取ります。

ビューはユーザーにフォームを表示します。ただし、ユーザーがp:commandButtonを押してフォームを送信すると、ビュースコープのBeanが再作成されたように見えるため(これを確認するために@PostConstructアノテーションを追加しました) 、 f:viewParamから読み取られたインスタンス変数を覚えていません。 (以下のコードのinvId)。

私は元々、URLパラメーターを含むGETを使用してビューに移動しましたが、ユーザーがp:commandButtonを押したときに送信されるPOSTメッセージにはURLパラメーターが含まていません。したがって、JSFランタイムがPOSTでURLパラメーターを認識しない場合、これは別のビューであると見なされ、JSF管理対象Beanを再作成していると思います。ビュースコープをセッションスコープに変更すると、コードは機能します。

コードは次のとおりです。

見る

<f:metadata>
    <f:viewParam name="invId" value="#{registerBean.invId}"/>
</f:metadata>
<h:form id="registrationForm">
     ....
    <p:commandButton value="register" action="#{registerBean.register}"
                     icon="ui-icon ui-icon-newwin" ajax="false"/>
</h:form>

バッキングビーン

@ManagedBean                                      
@ViewScoped
public class RegisterBean implements Serializable {
    @ManagedProperty(value="#{invId}")
    private String invId;
    ...

アップデート

これは、URLパラメータとはまったく関係がないことがわかりました。以下のBalusCのアドバイスに従って、ビューが使用していたc:whenタグを削除し(同じ効果を得る代わりにレンダリングされた属性に依存)、ビュースコープのBeanが再作成されなくなり、invIdフィールドが適切に保持されるようになりました。

4

1 に答える 1

8

この問題はこれまでに投稿されたコードには表示されませんが、JSF 2.0 / 2.1の場合、そのプロパティの1つがJSTL<c:if>やFacelets<ui:include>などのタグハンドラーの属性にバインドされたときにビュースコープのBeanが再作成されるという既知の問題です。部分的な状態保存が有効になっているときに、idおよびなどのJSFコンポーネントのビルド時間属性を表示bindingします(デフォルトの場合)。

背景の説明は、これらの属性のEL式は、ビューの構築および復元中に実行されるというものです。ビュースコープのBeanはビューに格納され、ビューを復元した後にのみ使用できるため、このようなEL式の評価により、まったく新しい個別のビュースコープのBeanが作成されます。これは基本的に鶏卵の問題です。これは、今後のJSF2.2で修正されています。

基本的に3つの解決策があります:

  1. それに応じてビューを変更し、これらのEL式がビューのレンダリング時にのみ評価されるようにします。たとえば、<c:if>/<c:choose>を。に置き換えrenderedます。
  2. または、これらの属性をリクエストスコープのBeanにバインドします(設計上の注意:ビュースコープのBeanをリクエストスコープのBeanの管理プロパティとして挿入できます)。
  3. 特定のビューに対してのみ必要な場合は、部分的な状態の保存をオフにします。

参照:

于 2013-01-08T14:21:09.827 に答える