目次


XPages アプリケーションにおけるセッション管理

XPages アプリケーションにおけるセッションデータ管理手法をマスターする

Comments

XPages アプリケーションにおけるセッション情報

XPages では、多種多様なプログラミングの要望に対応できるよう、さまざまなタイプのセッション情報保持の方法が提供されています。それぞれの方法ごとに、どのタイミングで初期化されどのタイミングで破棄されるのかが異なっており、それらを正確に理解し活用することは、XPages アプリケーション開発において必須のテクニックです。特に、タイムアウトなどにより破棄されるタイミングを正しく理解することが重要で、破棄された後にアクセスを行うと、正しい値が取得できないだけではなく、簡単に例外処理を引き起こす原因となります。その上、セッション情報の破棄に起因する問題は、アプリケーション開発初期の機能テストではタイムアウトが発生することが殆どないため発見されず、開発後期のロングランなどのシステム・テスト・フェーズになってから発見されることが多くなります。すでにロジックが固まっているこの段階で、問題解決のためにセッション情報の取り扱い方を変更するのは、アプリケーションのさまざまな部分に影響を及ぼす場合が多く、リスクの高い変更となってしまいます。そのようなリスクを避けるためには、アプリケーションの初期設計段階から、セッションのタイムアウトに対する対応をきちんと組み込んでおく必要があります。

セッション情報の種類

XPages において用意されているセッション情報を保持するための手段には以下のものがあります。

スコープ変数

XPages において最も一般的なセッション情報保持の手段は、スコープ変数を用いる方法です。スコープ変数とは、ある一定の期間、XPages のサーバーサイドの実行環境が自動で用意してくれる JavaScript オブジェクトです。スコープ変数にはそのアクセス範囲 (スコープ) の広い順に、アプリケーション/セッション/ビュー/リクエストの 4 種類が存在します。

スコープ変数をアクセスするには、以下の 2 つの方法が利用できます。

  • データバインドによるアクセス

    ページに配置したコントロールのデータソースとして、セッション変数をバインドすることができます。そうすることで、特に JavaScript によるロジックを記述しなくても、自動的に、そのコントロールの値としてユーザーとの間で入出力されるようになります。図 1 は、セッションスコープの変数として title という名前の変数を用意し、編集ボックスコントロールにデータバインドした例です。

    図 1. コントロールのデータソースとしてセッション変数をバインド
  • JavaScript ロジックによるアクセス

    スコープ変数は、JavaScript によるロジックで直接アクセスすることも可能です。JavaScript ロジック内では、アプリケーション/セッション/ビュー/リクエスト各スコープ変数が applicationScope/sessionScope/viewScope/requestScope という名前で用意されています。これらの変数は JavaScript のオブジェクトのため、任意のメンバー名を付けてアクセスを行います。

    リスト 1 は、データバインドによるアクセスと同じスコープ変数を JavaScript によりアクセスした例です。sessionScope オブジェクトに title というメンバーを追加して、文字列を代入しています。

    リスト 1. JavaScript ロジックによるスコープ変数のアクセス
    sessionScope.title = “アプリケーションのタイトル”

4 つのスコープ変数は、それぞれ以下のような特徴を持ちます。

(1) applicationScope

  • アクセス可能スコープ

    1 つの NSF で実現される XPages アプリケーションをアクセスする全ユーザーで共有されます。

  • 有効期間

    最初のユーザーが XPages アプリケーションをアクセスしたタイミングで初期化され、最後のユーザーのアクセスが行われた後、一定の時間が経過してタイムアウトが発生した時点で破棄されます。タイムアウト時間は IBM Domino Designer を利用して、「Xsp プロパティ」>「一般」>「タイムアウト」のセクションで「アプリケーションのタイムアウト」として設定します (図 2)。設定がない場合のデフォルト値は 30 分です。

    図 2. タイムアウトの設定
  • 利用方法

    同一アプリケーションの全ユーザー間で共有する必要がある情報を保持するために利用します。例えば、現在のアプリケーション利用者数を数えて表示したり、全ユーザーで共通かつ頻繁に利用する情報をキャッシュしたりするために有効です。

  • 内部実装手法

    該当 XPages アプリケーションがアクセスされ、そのアプリケーションがサーバーサイドの実行環境にロードされた時点で自動的に作成されます。

(2) sessionScope

  • アクセス可能スコープ

    複数のページから成る XPages アプリケーションで、全ページを通じて共有されます。ユーザーごとに独立して一つずつ用意されます。

  • 有効期間

    各ユーザーが初めて XPages アプリケーションをアクセスしたタイミングで初期化され、最後のアクセスが行われた後、一定の時間が経過してタイムアウトが発生した時点で破棄されます。タイムアウト時間は IBM Domino Designer を利用して、「Xsp プロパティ」>「一般」>「タイムアウト」のセクションで「セッションタイムアウト」として設定します (図 2)。設定がない場合のデフォルト値は 30 分です。

  • 利用方法

    もっとも一般的に利用されるセッション変数です。複数ページ間を遷移しても情報が維持されるため、ページ単位ではなく、アプリケーション全体を通じて保持する必要がある情報を格納します。例えば、ショッピングサイト・アプリケーションを構築する際に、ショッピングカート情報を保存します。各種商品のページを遷移しながら、購入したい商品を選択した際にその記録を追加し、最後の支払いのページでは、それらの合計を計算して表示するといった利用を行います。

  • 内部実装手法

    ユーザーが XPages アプリケーションをアクセスすると、サーバーサイドでは必ずセッション ID が割り当てられます。その ID は、クライアントサイド (ブラウザー) に SessionID という名前の cookie として伝えられます。2 回目以降の HTTP リクエストではヘッダーにその cookie 値が添えられるため、サーバー側はその HTTP リクエストがどのセッションに属するものかを判断できます。これにより、ページ間を遷移しても、同じセッションとしてのアクセスであることが認識できます。

    強制的にセッション情報をクリアしたい場合には、一旦ブラウザーを終了して改めて XPages アプリケーションをアクセスし直すか、この cookie 情報をクリアします。
    このセッション情報は、後述する IBM Domino サーバーに対する認証セッション情報とは完全に独立した情報です。

(3) viewScope

  • アクセス可能スコープ

    ユーザーごと、かつ、アプリケーションを構成するページごとに用意されます。

  • 有効期間

    それそれのページを最初にアクセスした時点で初期化され、同一のページから遷移することなく、部分更新でアクセスを続ける限り有効です。同一ページであっても、新規のアクセスを行った場合には、新規のビュースコープ変数が新たに生成され割り当てられるため、それまでの値は参照できなくなります。これは、同じページをブラウザーの複数のタブから同時にアクセスした際も同様です。複数のタブに同一のページが表示されますが、割り当てられているビュースコープ変数はそれぞれ異なります。

    ビュースコープ変数には、タイムアウト時間は存在しません。よって、最後のアクセスより一定時間が経過した時点で破棄されることはありません。ただし、同一ページに対して同時に存在可能な上限数が設定されているため、上限数を越えた時点で最後のアクセスが古いものから順に破棄されていきます。上限数は IBM Domino Designer を利用して、「Xsp プロパティ」>「永続性」>「永続性オプション」のセクションで「サーバーページの永続性」と「ディスク上の最大ページ数」として設定します (図 3)。ページをディスク上に保持する場合の上限数のデフォルトは 16、メモリー上に保存する場合の上限数のデフォルトは 4 です。

    また、アプリケーションスコープ変数が消滅するタイミングでも、そのアプリケーションに関する全ての情報が破棄されるため、ビュースコープ変数もその時点で破棄されます。

    図 3. ビュースコープ変数保持数の設定
  • 利用方法

    同一 XPages アプリケーション内であっても、ページ間で共有する必要のない情報を保持するために利用します。例えば、アプリケーション設定画面などで複数の設定項目を管理する必要があり、各項目間に関連性があるため、ユーザーが入力操作を行うごとに部分更新を利用してダイナミックに画面表示を更新していくような場合、入力された設定データを一旦ビュースコープ変数に保存して処理します。

    他の例としては、文書一覧ビューを表示するページを用意し、個別文書をクリックするたびに別タブを開いて同時に表示するような場合です。開いた文書に関する情報を、ビュースコープ変数を利用して保持することにより、同一ページを同時に複数開いても、それらを独立して扱うことが可能です。

  • 内部実装手法

    ユーザーが XPages アプリケーションのページを新規にアクセスすると、サーバーサイドではビューID が割り当てられます。その ID は、クライアントサイドに返信される HTML フォーム内の$$viewid という名前の隠し入力フィールド値として記録されています。次回ページ更新のサブミット時にはこの入力フィールド値が HTTP リクエストのパラメータとしてサーバーに送信されるため、どのビュースコープ変数に対応するアクセスであるかが認識できます。

(4) requestScope

  • アクセス可能スコープ

    単一の HTTP リクエスト処理の間のみアクセス可能です。HTTP リクエスト間で独立しています。

  • 有効期間

    ブラウザーより HTTP リクエストを受けた時点で初期化され、返信内容の HTML を計算し、返送が完了した時点で破棄されます。

  • 利用方法

    永続性の必要がない情報を一時的に保持するために利用します。例えば、ページがアクセスされた時点で呼び出される beforePageLoad イベント処理時に、後の処理で必要な値を計算して requestScope 変数に記録し、ページ内に配置された各コントロールの処理時にその値を参照するような場合です。

  • 内部実装手法

    永続性のないセッション変数のため、単純に HTTP リクエストを受けた時点で作成し、処理完了時点で破棄します。

以上が、4 種類のスコープ変数の標準的な動作ですが、これらの永続性に関する動作を無効にすることもできます。図 2 に示されたオプションのうち、「要求間でセッションを永続化する」オプションをはずすことにより、セッションスコープとビュースコープの永続性が無効になります。

スコープ変数の永続性を保つためには、各 HTTP リクエストを受けるごとに、処理開始前に前回のセッション情報を回復させ、処理完了時にその時点でのセッション情報をディスク上に記録するなどして、次回のリクエストに備えるといった処理を行う必要があります。永続性を必要としない単純なアプリケーションの場合には、これらの処理を行わないことにより、サーバーに対する処理負荷を軽減させることができます。

データソース

NSF 内に蓄積されている Notes 文書をアクセスするために利用するデータソース変数も、スコープ変数同様セッション情報の一種です。

  • データバインドによるアクセス

    document1 という名前でフォームに関連付けたデータソースを、編集ボックスコントロールにバインドした例が図 4 です。Notes 文書内の Subject フィールドの値が、この編集ボックスコントロールの入出力値として利用されます。

    図 4. コントロールのデータソースとしてデータソース変数をバインド
  • JavaScript ロジックによるアクセス

    リスト 2 は、データバインドによるアクセスと同じデータソース変数を、JavaScript ロジックを利用してアクセスし、値を取り出している例です。

    リスト 2. JavaScript ロジックによるデータソース変数のアクセス
    var title = document1.getItemValueString(“Subject”);

データソース変数は、XPages アプリケーションのページに紐付いて用意される変数のため、その挙動はビュースコープ変数に準じます。そのため、ページ間遷移では維持されず、同一ページでも異なるアクセスに対しては異なる変数が用意されます。

カスタムコントロール用コンポジットデータ

セッション情報の特殊例として、カスタムコントロールで利用される compositeData 変数があげられます。compositeData 変数とは、カスタムコントロール内でのみ有効な変数で、カスタムコントロールで独自プロパティを定義した際 (図 5)、その値をアクセスする場合に利用される変数です。

図 5. カスタムコントロールのプロパティ定義

図 5 のように定義されたプロパティを JavaScript ロジックからアクセスするには、リスト 3 のようなロジックとなります。

リスト 3. JavaScript ロジックによるカスタムコントロールプロパティのアクセス
var p1 = compositeData.param1;
var p2 = compositeData.param2;

compositeData 変数は、ページに配置されたカスタムコントロールに対応して用意される変数のため、その挙動はビュースコープ変数に準じます。

同一ページ内には同一カスタムコントロールを複数配置することができます。その場合には、それぞれのカスタムコントロールごとに異なる compositeData 変数が用意される点が、ビュースコープ変数とは異なる点です。compositeData は通常の JavaScript オブジェクトであり読み書きともに可能なため、独自プロパティの値をアクセスするためだけではなく、スコープ変数のように任意のメンバーを定義して値の読み書きを行うことも可能です。つまり、compositeData は、カスタムコントロールごとのローカル変数として利用することも可能だということです。

IBM Domino サーバーのユーザー認証との関係

IBM Domino サーバー上の XPages を含む全ての Web アプリケーションをアクセスする際には、ユーザー認証が行われます。この章では、このユーザー認証と XPages の管理するセッション情報との関係をまとめます。

Domino サーバーの行うユーザー認証には、大別して以下の 3 つのパターンが存在します。

(1) ユーザー認証を行わない匿名アクセス

アクセスしようとしている XPages アプリケーションの NSF が Default ユーザーにアクセス権を付与していた場合、その XPages アプリケーションのアクセスに対してはユーザー認証は行われず、匿名ユーザーとしてアクセスすることが可能です。

XPages アプリケーションでは、匿名ユーザーからのアクセスに対しても、上述したセッション情報の管理を行います。つまり、匿名ユーザーのアクセスが開始された時点で、セッション ID とビューID を発行し、それに対応する sessionScope 変数と viewScope 変数を初期化して割り当てます。

注意すべき点は、この後引き続きユーザー認証を行った場合です。ユーザー認証が成功した場合でも、あくまでも、IBM Domino サーバーによるユーザー認証の管理と、XPages 側で行っているセッション情報の管理は独立しており、XPages 側では利用ユーザーが匿名ユーザーから認証済みユーザーに切り替わっても、sessionScope 変数を再度初期化することはありません。

よって、表示内容を sessionScope に格納されたデータにより決定し、匿名アクセス時と認証ユーザーによるアクセス時に表示内容が変化するようなアプリケーションでは、ログインが行われたタイミングで、明示的に JavaScript のロジックを利用して sessionScope 変数を再度初期化する必要があります。

リスト 4 はそのような処理を行う一例です。このようなロジックを beforePageLoad イベント時に実行します。匿名ユーザーがログインしたことおよび認証済みユーザーがログアウトしたことは、前回アクセス時点の現行ユーザー名と、現在のユーザー名を比較して変化していることで判定が可能です。

リスト 4. 匿名ユーザーと認証済みユーザー切り替えに伴う sessionScope 変数の再初期化
// ユーザーが変化したら (ログイン/ログアウトしたら) 再読み込み
if (sessionScope.userName != @UserName()) {
  // アプリケーション実行に必要な sessionScope 変数の初期化
    :
    :
}
sessionScope.userName = @UserName();

(2) Basic 認証を利用したアクセス

Domino Web Engine のセッション認証を無効化した状態では、ユーザー認証には Basic 認証が利用されます。この認証操作は、XPages アプリケーションからは完全に独立しており、認証の前後で、XPages アプリケーションのセッション情報管理に関する動作に変化はありません。

(3) LTPAToken を利用したセッション認証によるアクセス

Domino Web Engine のセッション認証を有効化した状態では、ユーザー認証には LTPAToken を利用したセッション認証が利用されます。認証済みのユーザーには LTPAToken が DomAuthSessID という名前の cookie として発行されます。この cookie は XPages アプリケーションがセッション情報を管理するために発行している SessionID cookie とは完全に独立したものであり、Basic 認証の場合と同様、認証の前後で XPages アプリケーションのセッション情報管理に関する動作に変化はありません。

タイムアウト発生時の挙動

XPages アプリケーションにおいては、あらかじめアプリケーション全体で必要になるセッション情報を、ページを最初にアクセスした際に発生する beforePageLoad イベント処理内であらかじめ用意して sessionScope や viewScope 変数のメンバーとして格納しておき、各イベント処理時やコントロールの表示内容の計算時には、その情報を参照するのみとする手法が一般的です。この手法では、初期化ロジックが一箇所に集ることで、理解しやすく効率的なものになり、またコントロール表示内容の計算を不必要に繰り返すことがなくなることで、処理が高速化されます。

このようにして用意されたセッション情報に対して、タイムアウトが発生したためにスコープ変数が破棄され、次回アクセス時に問題が発生するのは sessionScope 変数を利用している場合が大半です。その際に発生する問題のパターンには、次の 2 種類があります。

(1) sessionScope 変数に単純変数をメンバーとして追加し、セッション情報として利用している場合

beforePageLoad イベント時には、リスト 5 のようにセッション情報の初期化を行います。これらの情報をページに配置したコントロール群に割り当て、画面表示を行う部分が図 6 になります。

リスト 5. 名前、住所、電話番号から成るセッション情報を単純変数で格納
sessionScope.name = “山田 太郎”;
sessionScope.addresss = “東京都中央区箱崎町”;
sessionScope.tel = “03-1234-5678”;
図 6. 初期化したセッション情報を表示するコントロール群

このアプリケーションを実行した結果は、図 7 のようになります。

図 7. 正常な実行結果

セッションタイムアウト時間が経過して、sessionScope が破棄されてしまった後に画面の更新 (部分更新による) を行うと、図 8 のようになってしまいます。リスト 5 で初期化した sessionScope 変数の各メンバー変数は、sessionScope 変数が一旦破棄された後再作成されているため、全て無効になってしまい値を持たないため、このような結果になります。但し、初期化されていない無効なメンバーであっても、図 6 のような形でアクセスされた際には、undefined の値を持つ変数として扱われるため、エラーとはなりません。

図 8. セッションタイムアウト後の実行結果

(2) sessionScope 変数にオブジェクトをメンバーとして追加し、セッション情報として利用している場合

beforePageLoad イベント時には、リスト 6 のようにセッション情報の初期化を行います。これらの情報をページに配置したコントロール群に割り当て、画面表示を行う部分が図 7 になります。

リスト 6. 名前、住所、電話番号から成るセッション情報をオブジェクトに整理して格納
sessionScope.person = {
  name: 	"山田 太郎",
  addr:	"東京都中央区箱崎町",
  tel:	"03-1234-5678"
}
図 9. 初期化したセッション情報を表示するコントロール群

このアプリケーションを実行した結果は、図 10 のようになります。正常に動作している場合には、(1) のケースとまったく同じ結果になります。

図 10. 正常な実行結果

セッションタイムアウト時間が経過して、sessionScope が破棄されてしまった後に画面の更新 (部分更新による) を行うと、図 11 のようになります。(1) のケースとは異なり、正しい値が表示されないだけではなく、実行時エラーとなってしまっています。

これは、リスト 6 で初期化した sessionScope 変数の person メンバー変数が、sessionScope 変数の破棄の後に再作成されているため、(1) と同様 undefined な変数となってしまっています。その上で今回のケースでは、それをオブジェクトとして扱い、更にそのメンバー変数 name をアクセスしようとしたため、処理継続不能の実行時エラーとなり異常終了してしまいます。

図 11. セッションタイムアウト後の実行結果

ここで利用したアプリケーションの例は非常に簡単なケースなため、問題発覚後でも修正はそれほど大変ではありません。しかしながら、実際のケースでは、より複雑な構造を持つセッション情報をより複雑な依存関係の下で扱っていた場合、修正は広範囲に及ぶ大掛かりなものになる可能性があります。アプリケーション開発の最終フェーズでこのような問題が発生することは、開発プロジェクトにとって大きなリスクとなってしまいます。

そのため、アプリケーション開発初期の段階から、セッションタイムアウト時の挙動を考慮した設計を行うことが重要です。

セッションタイムアウト発生を考慮したプログラム

セッションタイムアウトに対する対応の仕方には、さまざまなレベルのものがあります。

(1) 特別な対応を行わない

sessionScope 変数の利用方法が前章 (1) の単純変数メンバーを利用したものであった場合、タイムアウトが発生しても実行時エラーになることはなく、アプリケーションの実行そのものは継続されます。セッション情報がクリアされてしまっても、アプリケーションのユーザーが再入力すれば処理を継続することができるような単純なアプリケーションの場合には、特にタイムアウトに対して対応を行わないことも選択肢となります。sessionScope 変数の利用方法が前章 (2) のオブジェクトをメンバーとするものであった場合には、アプリケーションが異常終了してしまうため、この方法を利用することはできません。

(2) sessionScope 変数を利用せず、viewScope 変数のみを利用する

ページ間でセッション情報を維持する必要がないアプリケーションであれば、sessionScope 変数を利用せず、タイムアウトが発生しない viewScope 変数のみを利用してセッション情報を記録します。この方法でも、タイムアウトに対する特別な処理を必要としないため利用は簡単ですが、ページをまたがって情報を維持しなければいけない真の意味でのセッション情報を必要とするアプリケーションでは、この方法を利用することはできません。

(3) セッションタイムアウト時間を十分長いものに設定する

セッションタイムアウトの時間を、例えば 12 時間や 24 時間など、通常のアプリケーション継続利用時間を確実に越える時間に設定し、事実上 sessionScope のタイムアウトを発生させなくすることで、タイムアウトに対するロジックによる処理を省略します。この方法も、アプリケーションの設定を変更するだけで利用可能なため非常に簡単ですが、タイムアウト時間を長くすることは、維持が必要なセッション情報だけではなく、利用が終了してアクセスすることがなくなった、本来破棄されるべきセッション情報も同時にサーバー上で維持し続けることになり、IBM Domino サーバーのリソースを圧迫することになります。そのため、アプリケーション利用者数が多い、アプリケーションを継続して何度も利用と完了を繰り返す、といった環境では、JVM のヒープやディスクの空き容量といったサーバーリソースに十分な余裕があることを確認した上で、この方法を利用する必要があります。

(4) 定期的に IBM Domino サーバーをアクセスし、タイムアウトを発生させない

セッションタイムアウトは、ブラウザーからの最後のアクセスがなされた後、一定の時間が経過した際に発生します。よって、ブラウザーから IBM Domino サーバーへのアクセスを定期的に繰り返すことにより、タイムアウトの発生を防ぐことが可能です。IBM Domino 9.0 より標準でサポートされるようになった拡張ライブラリでは、この処理のための「セッションの維持」コントロールが提供されています。このコントロールをページ上に配置し、「ピングの頻度」を適切に設定するだけで、一定間隔でのアクセスを行ってくれます (図 12)。

図 12. 「セッションの維持」コントロールの利用

ユーザーの操作のあるなしに関わらず、常に最新の未読文書数を表示するといったような機能を求められるアプリケーションの場合には、クライアントサイドの JavaScript ロジックにより更新が必要な情報を定期的に部分更新することで、「セッションの維持」コントロールと同様の効果を得ることができます。この場合の定期アクセスは、情報更新のために真に必要なアクセスのため、「セッションの維持」コントロールによるセッション維持のためだけのアクセスに比べて無駄がありません。リスト 7 にサンプルコードを示します。

リスト 7. 定期的な自動部分更新ロジックの例
XSP.addOnLoad(function(){
  setInterval(function() {
    XSP.partialRefreshPost("#{id:partialUpdateTarget}");
  }, 60000);
});

これらの方法では、セッション維持が必要な期間中、常にブラウザー上で JavaScript が動作し続けていることを前提としています。そのため、クライアント PC がサスペンドしてしまうような環境では、サスペンドの間にセッションタイムアウト時間が経過してしまい、セッション情報が失われてしまう可能性があることに留意する必要があります。

(5) タイムアウトの発生を検出して、再初期化を行う

この方法では、タイムアウトの発生によりセッション情報が破棄されてしまうことは避けられないことと考え、破棄された場合にはそれを検出して再度セッション情報の初期化を行います。セッション情報は再度初期化されるため、正確に破棄直前の状態には戻りませんが、セッション情報は単にクリアされてしまった状態ではなく、正しく初期化された状態から再開されるため、ユーザーに対する影響を最小限に留めることができます。

この方法の場合、セッションタイムアウト発生の結果、再度初期化が行われていることをユーザーに対して明示的に通知することも有効です。

リスト 8 は、この方法を実現する際の beforePageLoad イベントのロジック例です。sessionScope.initialized 変数に、初期化済みかどうかを記録します。タイムアウトが発生してセッション情報が破棄された場合、この変数は自動的に undefined(=false) に変化します。

同様に、初期化済みであることを、クライアント側の cookie にも記録します。クライアント側のこの情報では初期化済みにもかかわらず、sessionScope.initialized が undefined であった場合、タイムアウトが発生しています。その場合には、その旨ユーザーに表示するためのフラグとして、requestScope.timeout を true に設定しています。requestScope 変数は現在の HHTP リクエスト処理の間だけ有効な変数のため、次回リクエスト時にはクリアされており、明示的に requestScope.timeout をリセットするロジックは不要です。

リスト 8. タイムアウト発生時セッション情報再初期化のコード例 1 – beforePageLoad イベント処理
if (!sessionScope.initialized) {
  // 以前初期化されたことがあるかどうかを、cookie の存在で判別
  if (cookie.get("sessionInitialized")) {
    // タイムアウト発生メッセージの表示を指示
    requestScope.timeout = true;
  }

  // 任意のセッション情報の初期化コード
    :
    :

// 初期化済みであることを cookie に記録
  var response = facesContext.getExternalContext().getResponse();
  var resCookie = new javax.servlet.http.Cookie("sessionInitialized", "true");

  // 初期化済みであることを sessionScope 変数に記録
  response.addCookie(resCookie);
}

部分更新の際にも、タイムアウトによるセッション情報の破棄を検出する必要があります。そのためのコードがリスト 9 です。afterRestoreView イベント処理内で、sessionScope.initialized を確認します。セッション情報が破棄されていた場合には、ページ全体を再ロードします。

リスト 9. タイムアウト発生時セッション情報再初期化のコード例 2 – afterRestoreView イベント処理
if (!sessionScope.initialized)
  context.reloadPage();

図 13 およびリスト 10 は、タイムアウトが発生したことをユーザーに知らせるメッセージに関するものです。リスト 8 のコードで用意した、requestScope.timeout の値により、メッセージの表示を制御します。

図 13. タイムアウト発生をユーザーに通知するラベルコントロール
リスト 10. ラベルコントロールの「可視」計算式
requestScope.timeout

(6) Notes 文書など永続的な記録を活用する

どのようケースにおいても、必ずセッション情報を維持する必要がある場合に、sessionScope 変数を利用するのではなく、NSF 内の Notes 文書に情報を記録しておく方法です。各 HTTP リクエストの処理開始時に Notes 文書からセッション情報を取り出し、処理完了時に毎回セッション情報を Notes 文書に書き出して保存します。各 HTTP リクエストがどのセッションに対する要求なのかを判断して、読み込み/書き出しを行う Notes 文書を決定するため、独自のセッション情報を cookie 等を利用して維持管理します。これ以外にも、不要になったセッションに対する Notes 文書を消去するエージェントを定期的に実行するなど、処理の重さ、必要とされるロジック量ともに、最もコストのかかる方法です。

まとめ

XPages アプリケーションでは、セッション情報を簡単に利用できるようになりました。その保持の方法には多様なものがあり、それぞれの特徴をよく理解した上で使い分けることが必要です。また、セッション情報は常にタイムアウトにより破棄されることを念頭に置き、多様な対処方法の中から最適なものを選択してアプリケーション開発初期の段階から実装することが重要です。


ダウンロード可能なリソース


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Lotus, Web development
ArticleID=977622
ArticleTitle=XPages アプリケーションにおけるセッション管理
publish-date=07172014