web-dev-qa-db-ja.com

@ViewScopedは、ポストバックリクエストごとに@PostConstructを呼び出します

これは正しくないようです。コードのクリーンアップを行っていたところ、これに気づきました。すべてのajaxリクエストは、コンストラクターと@PostConstructBeanの@ViewScopedを起動しています。単純なデータベースのページ付けでさえ、それを起動しています。

I 理解@ViewScoped@RequestScopedよりも長く、リクエストごとに再構築するべきではないこと。 GETによるページの完全なリロード後にのみ。

28
Drew H

つまり、@ViewScopedBeanは@RequestScopedBeanのように動作します。ポストバックリクエストごとに最初から再作成されています。これには多くの考えられる原因がありますが、そのほとんどは、関連付けられたJSFビューがJSF状態で使用できなくなり、デフォルトでHTTPセッションに関連付けられていることです。

HTTPセッション自体が問題の根本原因ではないことを確認できる場合、つまり@SessionScopedが完全に正常に機能する場合は、以下の考えられる原因のリストを確認してください。それ以外の場合、HTTPセッション自体も破棄され、すべてのリクエストで再作成される場合は、一歩下がってセッションcookieとサーバー構成を確認する必要があります。壊れたHTTPセッションに関連する原因は、少なくともJSFのコンテキストを超えています。

  1. Mojarra 2.1.17以前を使用しており、ビューには、ビュースコープのBeanプロパティを ビュービルド時間 の間に評価されるタグ属性にバインドするEL式が含まれています。例としては、JSTL <c:if><c:forEach>など、またはJSF <ui:include><x:someComponent id="#{...}"<x:someComponent binding="#{...}">などがあります。これは、Mojarraのバグが原因です( issue 1492 )。参照 Beanが@ViewScopedであるのに@PostConstructコールバックが毎回起動するのはなぜですか?JSF

    これは、Mojarraバージョン2.1.18ですでに修正されています。新しいバージョンにアップグレードできない場合の回避策は、以下のweb.xmlで部分的な状態保存を無効にすることです。 JSF2 FaceletsのJSTL ...意味がありますか? も参照してください。

    <context-param>
        <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
        <param-value>false</param-value>
    </context-param>
    

    または、特定のJSFビューのセットのみをターゲットにする場合:

    <context-param>
        <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
        <param-value>/foo.xhtml;/bar.xhtml;/folder/baz.xhtml</param-value>
    </context-param>
    

    言及することが重要なのは、JSFコンポーネントのidまたはbinding属性の値をビュースコープのBeanプロパティにバインドすることは悪い習慣であるということです。それらは実際にはリクエストスコープのBeanプロパティにバインドする必要があります。そうでない場合は、別のプロパティを探す必要があります。参照 JSFで「バインディング」属性はどのように機能しますか?いつどのように使用する必要がありますか?

  2. Mojarra 2.2.0を使用していますが、そのバージョンのみに、2.2.1ですでに修正されているビュースコープの維持に(まだ不明な)バグがあります。 問題2912 も参照してください。解決策は、新しいバージョンにアップグレードすることです。

  3. @ViewScopedアノテーションが間違ったパッケージからインポートされています。 JSFは、2つの@ViewScopedアノテーションを提供します。1つはjavax.faces.beanでアノテーションが付けられたJSFマネージドBean用の@ManagedBeanパッケージから、もう1つはjavax.faces.viewでアノテーションが付けられたCDIマネージドBean用の@Namedパッケージからです。 BeanスコープアノテーションがBean管理アノテーションと一致しない場合、実際のBeanスコープはBean管理フレームワークのデフォルトスコープになります。これは、JSF管理対象Beanでは@RequestScoped、CDI管理対象Beanでは@Dependentです。

    次の構成のいずれかがあり、それらを混在させないようにする必要があります。 JSF 2.2を使用する場合、ポストバック要求ごとに@ViewScoped Beanが再作成されます も参照してください。

    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    @ManagedBean
    @ViewScoped
    public class CorrectJSFViewScopedBean implements Serializable {
    
    import javax.inject.Named;
    import javax.faces.view.ViewScoped;
    
    @Named
    @ViewScoped
    public class CorrectCDIViewScopedBean implements Serializable {
    
  4. ビューは(偶然に?)<f:view transient="true">を介して一時的なものとしてマークされます。これにより、基本的に「ステートレスJSF」がオンになります。これは、Mojarra2.1.19以降の新機能です。これにより、JSFビューはJSF状態で保存されなくなり、論理的な結果として、参照されているすべてのビュースコープのBeanをJSFビューに関連付けることができなくなります。も参照してください JSFでのステートレスの有用性は何ですか?

  5. Webアプリケーションは、trueを「回避」しようとする誤った試みで、com.Sun.faces.enableRestoreView11Compatibility contextparamをViewExpiredExceptionに設定して構成されています。このコンテキストパラメータを使用すると、ViewExpiredExceptionがスローされることはありませんが、ビュー(および関連するすべてのビュースコープのBean)は最初から再作成されます。ただし、それがすべてのリクエストで発生する場合、このアプローチは実際には別の問題を隠します。ビューの有効期限が早すぎるということです。これは、JSFビューステートやHTTPセッションの維持に問題がある可能性があることを示しています。それを適切に解決/構成する方法は、 javax.faces.application.ViewExpiredException:ビューを復元できませんでした に進んでください。

  6. Webアプリケーションのランタイムクラスパスは、複数の異なるバージョンのJSFAPIまたはimpl関連クラスで汚染されています。これにより、JSFビューステートの識別子/マーカーに破損/不一致が発生します。 webappの/WEB-INF/libに複数のJSFAPIJARファイルがないことを確認する必要があります。 Mavenを使用している場合は、サーバーが提供するライブラリを<scope>provided</scope>としてマークするように注意してください。 JSF wikiページ の「JSFのインストール」セクションおよびこの関連する質問への回答も参照してください: Mavenを介してJSFライブラリを適切にインストールおよび構成する方法

  7. PrimeFaces <p:dialog>を使用している場合は、<p:dialog>に独自の<h:form>があり、別の<h:form>にネストされていないことを確認してください。 p:dialog内のp:fileUploadが@ViewScoped値を失う も参照してください。

  8. PrimeFaces FileUploadFilterをPrettyFacesと組み合わせる場合は、FileUploadFilterがPrettyFacesで書き換え/転送されたリクエストでも実行されることを確認してください。参照 FileUploadListenerがPrettyFacesを使用して呼び出されたときに再構築されたViewScoped Bean および PrimeFaces p:fileUploadの使用方法?リスナーメソッドが呼び出されないか、UploadedFileがnull /エラーをスローする/使用できない

  9. PrettyFacesを使用している場合、CSS/JS /画像リソースを@ViewScopedBeanに関連付けられたJSFページにリダイレクトする不適切に構成された書き換えルールも誤解を招く動作を引き起こします。参照 CDI ViewScope&PrettyFaces:@PostConstruct(JSF 2.2)への複数の呼び出し

51
BalusC