web-dev-qa-db-ja.com

com.Sun.faces.numberOfViewsInSessionとcom.Sun.faces.numberOfLogicalViews

JSF 2のMojarra実装には、次のコンテキストパラメータがあります。

  • com.Sun.faces.numberOfViewsInSession(デフォルトは15)
  • com.Sun.faces.numberOfLogicalViews(デフォルトは15)

それらの違いは何ですか?ドキュメントはこれらについてあまり語っていません。私のアプリは一部のページでViewExpiredExceptionに問題がありましたが、これらの設定を(はるかに)高い値に変更した後、問題が発生しなくなりました。

私のアプリは、財務が多く、フォームが多く、ajax対応のアプリです(一部の画面には50以上の入力があり、AJAXを介してさらに多くのデータ/入力を追加するオプションがあります)。

この行動の原因は何ですか?最初のパラメーターはセッションで保持される「ページ」の数を定義することを理解しています。これは[戻る]ボタンに役立つ場合がありますが、ViewExpiredExceptionをトリガーする私のユースケースでは[戻る]ボタンを使用しません。 2番目のパラメーターは何を指しますか?同じ画面のままで、AJAXを介して多くのデータを追加し続けると、ページの論理ビューの数を増やす必要がありますか?

36
Miguel Ping

まず第一に、Mojarra実装はそれらのコンテキストパラメータの意味を意図せず入れ替えました。したがって、説明がリテラルコンテキストパラメータ名が意味するものとまったく逆であるという印象を持っている場合、これは実際に当てはまります。


com.Sun.faces.numberOfLogicalViews

これは基本的にGETリクエストベースです。すべてのGETリクエストは、セッション中に新しいビューを作成します。

それを試すには、値を3に設定して、新しいブラウザーセッションを開始し、4つの異なるブラウザータブ(URLに関係なく、同じである場合も異なる場合もあります)を順番に開いてから、最初のタブに戻って送信しますそこのフォーム。このビューはセッション中のビューのLRU(Least Recently Used)マップからプッシュされているため、ViewExpiredExceptionを取得します。最大3つのタブを開いた場合、これは起こりません。

デフォルト値15では、これはまれな現実の問題です。 Webアプリケーションが実際にこのように使用されるように設計されている場合(たとえば、ディスカッションフォーラムやQ&Aなどの複数のタブで開かれるように招待するソーシャル/コミュニティサイト)、デフォルト値を増やす代わりに、クライアント側の状態保存を使用することを検討できます。 。クライアント側の状態保存では、この例外に直面することはありません。別の方法としては、リクエストスコープBeanとリクエストパラメータを組み合わせて OmniFaces <o:enableRestorableView> を使用するか、独自の状態を復元する必要があるかどうかを(ポスト)構築でチェックインするビュースコープBeanを使用します。もう1つの代替案は、 stateless with <f:view transient="true"> を実行することです。これにより、ビューは保存されなくなりますが、ビュースコープBeanは使用できなくなります。

MyFacesで同等のものは org.Apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION で、デフォルトは20です。


com.Sun.faces.numberOfViewsInSession

これは基本的に同期です(非Ajax!)POST要求ベース。同期POST要求ごとに新しい論理ビューが作成されます。これらはすべて物理ビューはMap<PhysicalView, Map<LogicalView, ViewState>>に似ています。したがって、最大15の物理ビューと最大15の論理ビューを使用すると、理論的にはセッションで15 * 15 = 225ビューを使用できます。

実験するには、値を3に設定し、同期フォームでビューを開き、4回送信してから、ブラウザーの戻るボタンを4回押してから、フォームを再度送信します。このビューは論理ビューのLRU(Least Recently Used)マップからプッシュされているため、ViewExpiredExceptionを取得します。これは、最大3回戻ってから再送信した場合には起こりません。

Ajax送信は同じ論理ビューを再利用することに注意してください(これは、ajaxポストバックで返されるまったく同じjavax.faces.ViewState値を確認することで確認できます)。とにかく、ブラウザの戻るボタンはサポートされていません。ブラウザーの[戻る]ボタンを押すと、前の同期リクエストに戻るだけなので、これらのすべてのajaxポストバックをセッションの論理ビューとして保存しても意味がありません。

デフォルト値が15で、現在のajax専用フォームの傾向と動的ページでのキャッシュの無効化により、これは非常にまれな現実の問題です。適切に設計されたフォームは、ブラウザの戻るボタンを押すように勧めるべきではありません。代わりに、送信が成功するとターゲットビューにリダイレクトされ、失敗すると検証エラーのある同じフォームが再表示されます。ヒントも参照してください JSFでナビゲートする方法?URLに現在のページを反映させる方法(前のページは反映しない) 。また、動的ページではキャッシュが無効にされることが多いため、[戻る]ボタンをクリックすると、新しいビューに戻ることができます。 JSF Webアプリケーションの戻るボタンを回避する も参照してください。これがアプリケーションにも当てはまる場合は、値を安全に1に設定できます。

MyFacesには元々これに相当するものはなく、これもセッション中の物理的なビューとして数えられました。バージョン2.0.6では、同様の目的で org.Apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION が導入されましたが、実装が異なり、デフォルトで無効になっています。


以下も参照してください。

66
BalusC

これをウェブで見つけました: http://oss.org.cn/ossdocs/Java/ee/javaeetutorial5/doc/JSFConfigure11.html

これは役に立つかもしれません:

論理ビューは、トップレベルのビューのサブビューです。たとえば、複数のフレームを含むページがある場合、各フレームは論理ビューです。単純なアプリケーションの場合、デフォルトの15ビューまたは15論理ビューは大きすぎる可能性があります。この場合、メモリを節約するために、ビューと論理ビューの許容数を減らすことを検討する必要があります。逆に、より複雑なアプリケーションでは、セッションに15以上のビューまたは論理ビューを保存する必要がある場合があります。

5
tasel