web-dev-qa-db-ja.com

JSFがサーバー上のUIコンポーネントの状態を保存する理由

  1. JSFはどの時点でサーバー側のUIコンポーネントの状態を保存し、UIコンポーネントの状態情報はサーバーメモリから正確に削除されますか?アプリケーションにログインしているユーザーがページをナビゲートすると、コンポーネントの状態はサーバーに蓄積され続けますか?

  2. わかりませんサーバー上でUIコンポーネントの状態を維持することの利点は何ですか??検証/変換されたデータをマネージドBeanに直接渡さないか?それを避けることができますか?

  3. 数千の同時ユーザーセッションがある場合、サーバー側であまりにも多くのメモリを消費しませんか?ユーザーが特定のトピックに関するブログを投稿できるアプリケーションがあります。このブログは非常に大きなサイズです。ブログのポストバックまたはブログの表示要求がある場合、このビッグページデータはコンポーネントの状態の一部として保存されますか?これは食べるでしょうメモリが多すぎます。これは心配ではありませんか?


更新1:

JSFの使用中に状態を保存する必要がなくなりました。高性能のステートレスJSF実装を使用できます。関連する詳細と議論については、こちらをご覧ください ブログこの質問 また、JSFにステートレスモードを提供するオプションであるJSF仕様に含めるためのオープン issue があります。 (P.S.問題に投票することを検討してください thisthis これが便利な機能である場合)


更新2(24-02-2013):

Mojarra 2.1.19は、ステートレスモードとともにリリースされました。

こちらをご覧ください:

http://weblogs.Java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://Java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

103
Rajat Gupta

なぜJSFはサーバー側でUIコンポーネントの状態を保存する必要があるのですか?

HTTPはステートレスであり、JSFはステートフルであるためです。 JSFコンポーネントツリーは、動的な(プログラム的な)変更の影響を受けます。 JSFは、フォームがエンドユーザーに表示されたときの状態を正確に知る必要があるため、フォームが送信されたときに元のJSFコンポーネントツリーから提供された情報に基づいてJSFライフサイクル全体を正常に処理できますサーバー。コンポーネントツリーは、要求パラメーター名、必要なコンバーター/バリデーター、バインドされたマネージドBeanプロパティおよびアクションメソッドに関する情報を提供します。


JSFはサーバー側のUIコンポーネントの状態をどの時点で保存し、UIコンポーネントの状態情報はサーバーメモリから正確に削除されるのですか?

これらの2つの質問は、同じものに要約されるようです。とにかく、これは実装固有であり、状態がサーバーまたはクライアントのどちらに保存されるかにも依存します。少しまともな実装では、有効期限が切れたときやキューがいっぱいになったときに削除されます。たとえば、状態保存がセッションに設定されている場合、Mojarraにはデフォルトで15の論理ビューの制限があります。これは、web.xmlの次のコンテキストパラメーターで構成できます。

<context-param>
    <param-name>com.Sun.faces.numberOfLogicalViews</param-name>
    <param-value>15</param-value>
</context-param>

Mojarra FAQ 他のMojarra固有のパラメーターとこの関連する回答について com.Sun.faces.numberOfViewsInSession vs com.Sun.faces.numberOfLogicalViews


アプリケーションにログインしているユーザーがページをナビゲートすると、コンポーネントの状態はサーバーに蓄積し続けますか?

技術的には、実装に依存します。ページ間のナビゲーション(GET要求のみ)について話している場合、Mojarraはセッション中に何も保存しません。ただし、POSTリクエスト(コマンドリンク/ボタンのあるフォーム))の場合、Mojarraはセッション内の各フォームの状態を最大制限まで保存します。これにより、エンドユーザーは異なるブラウザータブで複数のフォームを開くことができます。同じセッションで。

または、状態の保存がクライアントに設定されている場合、JSFはセッションに何も保存しません。これは、web.xmlの次のコンテキストパラメーターで実行できます。

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

次に、フォームのjavax.faces.ViewStateという名前の非表示の入力フィールドで暗号化された文字列にシリアル化されます。


サーバー側でUIコンポーネントの状態を維持することの利点が何であるか理解できません。検証/変換されたデータを管理対象Beanに直接渡すだけでは不十分ですか?それを避けることができます/すべきですか?

JSFの整合性と堅牢性を確保するには、それだけでは不十分です。 JSFは、単一のエントリポイントコントロールを持つ動的フレームワークです。状態管理がなければ、特定の方法でHTTPリクエストをスプーフィング/ハッキング(たとえば、disabledreadonly、およびrendered属性を操作)して、JSFに異なることをさせることができます-潜在的に危険なこと。 CSRF攻撃やフィッシングも発生しやすくなります。


そして、数千の同時ユーザーセッションがある場合、それはサーバー側であまりにも多くのメモリを消費しませんか?ユーザーが特定のトピックに関するブログを投稿できるアプリケーションがあります。このブログは非常に大きなサイズです。ブログのポストバックまたはブログの表示要求がある場合、大きなブログはコンポーネントの状態の一部として保存されます。これは、大量のメモリを消費します。これは心配ではありませんか?

メモリは特に安価です。 appserverに十分なメモリを与えてください。または、ネットワーク帯域幅が安価な場合は、状態をクライアント側に切り替えるだけです。最適な一致を見つけるには、ストレステストを行い、予想最大同時ユーザー数でwebappのプロファイルを作成し、最大測定メモリの125%〜150%をアプリサーバーに与えます。

JSF 2.0では状態管理が大幅に改善されていることに注意してください。部分的な状態を保存することは可能です(例えばonly<h:form>からすべてのものの代わりに<html>が保存されます最後まで)。たとえば、Mojarraはそれを行います。 10個の入力フィールド(それぞれにラベルとメッセージがあります)と2個のボタンがある平均的なフォームは、1KBを超えることはありません。セッションで15ビューを使用する場合、セッションごとに15KB以下にする必要があります。最大1000の同時ユーザーセッションでは、15MB以下にする必要があります。

セッションまたはアプリケーションスコープ内の実際のオブジェクト(マネージドBeanまたはDBエンティティ)にさらに焦点を当てる必要があります。セッションスコープBeanのフレーバーでデータベーステーブル全体をJavaのメモリに不必要に複製する多くのコードとプロジェクトを見てきました。ここで、SQLの代わりにJavaがフィルタリング/グループ化/配置に使用されますレコード:〜1000レコードでは、ユーザーセッションごとに10MBを簡単に超えることになります

196
BalusC