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 固有のパラメーターについてはMojarra FAQも参照してください。また、この関連する回答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 リクエストを特定の方法でスプーフィング/ハッキングして (たとえばdisabled
、readonly
やrendered
属性を操作するなど)、JSF にさまざまな (そして潜在的に危険な) ことをさせることができます。CSRF 攻撃やフィッシングの被害を受ける可能性さえあります。
また、何千もの同時ユーザー セッションがある場合、サーバー側で大量のメモリを消費しませんか? ユーザーが特定のトピックに関するブログを投稿できるアプリケーションがあります。このブログのサイズはかなり大きいです。ポストバックまたはブログの閲覧要求がある場合、大規模なブログはコンポーネントの状態の一部として保存されます。これは大量のメモリを消費します。これは気になりませんか?
メモリは特に安価です。アプリケーションサーバーに十分なメモリを与えるだけです。または、ネットワーク帯域幅の方が安い場合は、状態保存をクライアント側に切り替えるだけです。最適な一致を見つけるには、予想される同時ユーザーの最大数を使用して webapp のストレステストとプロファイリングを行い、appserver に測定された最大メモリの 125% ~ 150% を与えます。
JSF 2.0 では状態管理が大幅に改善されていることに注意してください。部分的な状態を保存することもできます (たとえば、最後までの全体ではなく、のみが保存されます)。たとえば、モハラはそれを行います。10 個の入力フィールド (それぞれにラベルとメッセージがあります) と 2 つのボタンを含む平均的なフォームは、1KB しかかかりません。セッションに 15 個のビューがある場合、セッションごとに 15KB を超えないようにする必要があります。最大 1000 の同時ユーザー セッションでは、15MB を超えないようにする必要があります。<h:form>
<html>
あなたの懸念は、セッションまたはアプリケーションスコープ内の実際のオブジェクト (マネージド Bean および/または DB エンティティ) にもっと集中する必要があります。SQL の代わりに Java を使用してレコードをフィルタリング/グループ化/配置するセッション スコープ Bean のフレーバーで、データベース テーブル全体を Java のメモリに不必要に複製する多くのコードとプロジェクトを見てきました。最大 1000 レコードの場合、ユーザー セッションごとに 10 MB を簡単に超えてしまいます。