ShowTable of Contents
XPages でアプリケーションのステータスを記憶するためのパーシステントな変数として、applicationScope, sessionScope,
viewScope, requestScope の4つのスコープ変数が用意されています。
また、スコープ変数に準じるもうひとつのパーシステントな変数として、カスタムコントロール内でカスタムプロパティを
アクセスするための compositeData があります。
これらはいずれもグローバルな変数としてシステム側で自動的に用意され、アプリケーション内の任意のロジック内で
アクセス可能です。(*1)
(*1) 例外として、beforeRenderResponse, afterRenderResponse, afterRestoreView のイベント
処理ロジック内で compositeData をアクセスするとエラーになることがあります。
これは 8.5.2 での制限事項であり、将来的に修正される可能性があります。
パーシステント変数の有効範囲
各パーシステント変数に代入された値の有効範囲と有効期間は、それぞれ以下の通りとなります。
applicationScope
NSF アプリケーション単位で有効となります。最初のユーザーによるアプリケーションのアクセスにより初期化され、
全ユーザーのセッション間で値が共有されます。いずれかのユーザーによる最後のアクセスより一定の時間後
タイムアウトにより破棄されます。
デフォルトのタイムアウト時間は30分です。タイムアウト時間は、各 NSF アプリケーションごとに設定可能です。
設定は
「アプリケーションのプロパティ」>
「XPage」>
「エラーとタイムアウト」で行います。
実際のタイムアウトは、指定した値よりも多少長めで発生します。
sessionScope
各ユーザーがブラウザを起動後、NSF アプリケーションを最初にアクセスした時点で初期化され、アクセスを継続する間有効となります。
ブラウザを終了する、一定時間アクセスが無くタイムアウト時間が経過する、のいずれかが発生した時点で破棄されます。
値はページを遷移しても保持され続けるため、オンラインショッピングのショッピングカートなどを実現するために利用します。
デフォルトのタイムアウト時間は30分です。タイムアウト時間は、各 NSF アプリケーションごとに設定可能です。
設定は
「アプリケーションのプロパティ」>
「XPage」>
「エラーとタイムアウト」で行います。
実際のタイムアウトは、指定した値よりも多少長めで発生します。
viewScope
NSF アプリケーション内の各ページが最初にアクセスされた時点で初期化され、アクセスがそのページ内にとどまる限り
有効です。別の言い方をすると、各ページを HTTP GET でアクセスした時点で初期化され、そのページ内で部分更新を
行うなど、HTTP POST を続ける限り有効となります。同一ページへのアクセスであっても、リンクによる遷移やブラウザの
リロードボタンによる HTTP GET であった場合には、再度初期化されます。
有効期限に関しては、セッションタイムアウトの影響は受けませんが、アプリケーションタイムアウトによりアプリケーション全体が
破棄された場合には、同時に破棄されます。また、これ以外に破棄が発生する条件として、セッションあたりの状態保持ページ数
の上限にも影響があります。こちらの詳細に関しては、以下のページ内の
「注意点」の章を参照してください。こちらの
記述にある「ページの破棄」が発生した場合、viewScope も同時に破棄されます。
XPages のビューコントロールのリンクを別ウインドウで開くようにする
requestScope
各ページのアクセスごとに初期化され、レスポンスを返した時点で破棄されます。ページの新規ロード (HTTP GET)、
部分更新 (HTTP POST) いずれの場合にも同様です。
compositeData
本来この変数は、カスタムコントロール内のロジックが、設定されたカスタムプロパティを取得するために用いる変数です。
しかしながら、スコープ変数と同様、値を代入することも可能で、XPage 内に配置された各カスタムコントロールごとに別々に
用意されるため、カスタムコントロールのプライベート変数のように用いることができます。こちらの詳細に関しては、以下の
ページを参照してください。
XPages のカスタムコントロールでプライベート変数を利用する
変数の有効期限に関しては、スコープ変数の viewScope 変数に準じます。
もうひとつのタイムアウト
XPages アプリケーションにおいてタイムアウトが発生するもうひとつのものに、セッション認証があげられます。
XPages アプリケーションをアクセスする際には、従来の Domio Web アプリケーションのセキュリティモデルが
適用されます。アクセス制限のかかった XPages アプリケーションをアクセスするためにはログインが必要で、
Domino Web Engine の設定としてセッション認証が設定されている場合、一定期間アクセスが無かった場合には
その認証情報は無効となります。
このタイムアウト時間は、サーバー文書の
「インターネットプロトコル」>
「Domino Web Engine」>
「HTTP セッション」
で設定されています。デフォルトのタイムアウト時間は30分です。
アプリケーション全体にアクセス制限がかかり、ログインしなければ一切のアクセスができないタイプのアプリケーションでは、
このタイムアウトはそれほど気にする必要がありませんが、ログイン前の匿名アクセスでも一定のアクセスが可能で、
ログインすると表示される内容がログインユーザーごとに変化するようなタイプのアプリケーションでは、
アプリケーション内のロジックでこのセッション認証のタイムアウトを意識する必要があります。
タイムアウト発生時の注意点
これまで述べたとおり、各種パーシステント変数およびセッション認証はタイムアウト等が発生して無効になることがあります。
その際には、次回のアクセスが発生した時点で再初期化され、無効化する以前の値が全て失われた状態でアプリケーション
の実行が継続されます。そのため、アプリケーション内のロジックは、常にこのようなケースが発生することを念頭に、
コーディングされる必要があります。
通常、この「次回のアクセス」が新規ページのアクセス (HTTP GET) であった場合にはあまり問題にならない場合が
多いのですが、表示されたまま放置されていたページで部分更新を起こすアクセス (HTTP POST) であった場合には、
特に注意が必要です。
例えば、以下のようなケースではセッションタイムアウト発生後のアクセスでアクセス例外が発生してしまいます。
ページ全体で利用するデータを、文書に保存されている情報などからページロード時にあらかじめ sessionScope変数などに
JavaScript のオブジェクトとして初期化しておき、ページ内の各コントロールはそのオブジェクトを参照しながら動作することを
考えます。
データの初期化に複雑な計算が必要で重たい処理であり、その処理結果をページ内の多くのコントロールで
参照しているような場合に、このような構成にする場合があります。
この場合、beforePageLoad イベントのロジックとして、以下のようなオブジェクトの初期化を行います。
sessionScope.personData = {
name: "日本太郎",
age: 30,
gender: '男',
address: '横浜市',
phone: '045-111-2222'
};
ページ内に配置されたコントロール、例えば計算結果フィールドで、以下のようなアクセスを行います。
'名前は ' + sessionScope.personData.name + 'です'
更に、このページ内にはこのコントロールを部分更新するようなボタンが組み込まれているものとします。
このページを最初にアクセスした際には、アプリケーションは期待した通りの動作します。部分更新の機能も駆使した、
洗練された Web 2.0 エクスペリエンスを提供できるでしょう。
ところが、このページをセッションタイムアウトが発生するまでブラウザで表示したまま放置した後、ユーザーが
部分更新を起こすボタンを押した場合には、sessionScope はタイムアウトで破棄されているため新規作成され、
その結果 sessionScope に保存されていた personData オブジェクトが消えた状態で、計算結果フィールドの
ロジックが評価されます。その時点でアクセス例外が発生してしまいます。
この問題を解決するためには、例えば beforePageLoad で実行されるロジックを beforeRenderResponse に移動し、
以下のような変更を加えます。
if (sessionScope.personData == null) {
sessionScope.personData = {
name: "日本太郎",
age: 30,
gender: '男',
address: '横浜市',
phone: '045-111-2222'
};
}
beforeRenderRespose イベントは、部分更新の HTTP POST アクセス時にも実行されるため、タイムアウト発生後は
personData の再初期化が行われます。これにより、アクセス例外が発生することはなくなります。
問題の回避にはケースバイケースでいろいろな方法が考えられますが、この方法でも、ユーザーが編集途中の情報を
sessionScope に蓄積するようなロジックであった場合には、セッションタイムアウトが発生した時点で、その情報は
全て失われることになります。
sessionScope を利用する場合だけでなくその他のパーシステント変数を利用している場合でも、同様な問題が
発生することがあり得ます。
また、パーシステント変数のタイムアウトだけではなく、セッション認証のタイムアウトでも同様です。ユーザーがログイン
しているかどうかで表示内容が変わるようなアプリケーションであった場合、ログイン後、そのユーザーでアクセス可能な
情報を表示させた状態でブラウザを放置し、認証がタイムアウトした後に部分更新が発生する操作を行った場合、
アクセス権が失われているため例外を発生させてしまうかもしれません。
sessionScope変数などは従来の Domino Web アプリケーションでは利用できなかったものであり、Web アプリケーションを
構築する再には非常に便利な機能なのですが、常に、上述のようなタイムアウトが発生することがありうることに注意して、
ロジックを記述するようにしましょう。