7章 セッション (Sessions)

 

ハイパーテキスト転送プロトコル(HTTP)はステートレスとして設計されたものである。効果的なWebアプリケーションとするために、あるクライアントからの一連の異なった要求が相互に関連させることが肝要である。多くのセッション トラッキングの方法が進化してきてはいるが、プログラマがそれを直接使うにはそれらの総てが難しいか、トラブルの種となるものであった。

 

本仕様では、単純なHttpSessionインターフェイスが用意されており、これにより個々のクライアントからのアプローチに開発者を巻き込まなくても、サーブレット コンテナはどんな数のアプローチでもユーザのセッションを追いかけるために使うことができる。

 

 

7.1 セッション トラッキングのメカニズム (Session Tracking Mechanisms)

 

 

7.1.1 URL再書き込み (URL Rewriting)

 

URL再書き込みはセッショント ラッキングの最小公分母である。クライアントがcookieを受け付けないときは、サーバはセッション トラッキングを確立するのにURL再書き込みを使用して良い。URL再書き込みは、URLパスにデータを追加して、次の要求に際してコンテナがあるセッションとの関連付けを解釈できるようにする。

 

結果としてのURLストリングのパス パラメタとしてセッションID(session id)がエンコードされねばならない。パラメタの名前はjsessionidでなければならない。パス情報がエンコードされたURLに一例を示すと:

 

http://www.myserver.com/catalog/index.html;jsessionid=1234

 

 

7.1.2 クッキー (Cookies)

 

HTTP cookiesを介してのセッション トラッキングは一番多用されるセッション トラッキングのメカニズムで、総てのサーブレット コンテナがサポートすることが要求されている。コンテナはcookieをクライアントに送出する。クライアントは次にその後に引き続くサーバへの要求上にそのcookieを返す。この要求はクライアントでは一義的に該要求とセッションを対応させる。セッション トラッキングcookieの名前はJSESSIONIDでなければならない。

 

 

7.1.3 SSLセッション (SSL Sessions)

 

セキュアなソケット層(Secure Socket Layer)、即ちHTTPSで使われている秘匿技術は、クライアントからの複数の要求が、受理されたセッションの一部であるかの明確な識別のためのメカニズムが組み込まれている。サーブレット コンテナは簡単にこのデータをセッション定義のメカニズム用に使うことが出来る。

 

 

7.2 セッションの生成

 

HTTPは要求/応答ベースのプロトコルである為、クライアントがそれに参加(joins)するまではセッションは新しいと考えられる。セッションが確立されたことを意味するセッショントラッキング情報がサーバに無事返されたとき、クライアントはこのセッションに参加したことになる。クライアントがセッションに参加するまでは、次に到来する該クライアントからの要求をそのセッションの部分であると仮定してはいけない。

 

以下のいずれかが成立すれば、セッションはnewであると考えられる:

 

-           クライアントがまだ本セッションを知っていない

-           クライアントがセッションに参加しないことを選択している。このことは、サーブレットコンテナはこれによって前回の要求と今回の要求を関連付けするメカニズムを有さないということを意味する。

 

サーブレット開発者は彼らの開発したアプリケーションが、クライアント セッションにがまだ参加していないか、あるいは参加しようとしていない事態にも対応できるようにしておかねばならない。

 

 

7.3 セッションのスコープ (Session Scope)

 

HttpSessionオブジェクトは、application / servletコンテキストレベルでスコープされていなければならない。その下のメカニズム、例えばセッション確立のために使われるcookieなどは、コンテキスト間で共用できが、このオブジェクトは開示されており、もっと重要なことはそのオブジェクトの属性は二つのコンテキスト間で共用されてはいけない。

 

 

7.4 属性のセッションへのバインド (Binding Attributes into a Session)

 

サーブレットはオブジェクトの属性をHttpSessionインプリメンテーションに名前でバインドすることができる。あるセッションへバインドされたどのオブジェクトも同じServletContextに属する他のサーブレットからもアクセス可能であるし、他のサーブレットが該要求を同じセッションの部分であると識別することが出来る。

 

オブジェクトによっては、それがあるセッションに配置されたとか外されたとかしたときに通知する必要がある場合もある。この情報はオブジェクトがHttpSessionBindingListenerインターフェイスを実装することで取得できる。このインターフェイスでは、オブジェクトがバインド中であるか、あるいはバインドから外されつつあるかを通知する為の以下のメソッドが定義されている。

 

-           valueBound

-           valueUnBound

 

valueBoundメソッドはオブジェクトがHttpSessionインターフェイスのgetAttributeメソッドによりオブジェクトがアクセス可能になる前に呼ばれなければならない。valueUnBoundHttpSessionインターフェイスのgetAttributeメソッドを介してもはやアクセス不可能となったあとで呼ばれねばならない。

 

 

7.5 セッションのタイムアウト (Session Timeouts)

 

HTTPプロトコルにおいては、クライアントがもはやアクティブで無くなったときの明示的な終了信号といったものは存在しない。このことは、クライアントがもはやアクティブで無くなったことを示す唯一つのメカニズムはタイムアウトであることを意味する。

 

セッションのデフォルトのタイムアウト期間はサーブレットコンテナで定義され、HttpSessionインターフェイスのgetMaxInactiveIntervalメソッドにより取得できる。このタイムアウトは、開発者がHttpSessionインターフェイスのsetMaxInactiveIntervalメソッドを使って変更が可能である。これらのメソッドで使われているタイムアウト期間は秒で定義されている。そのセッションのタイムアウト期間が-1にセットされているときは、該セッションはタイムアウトを発生させない。

 

 

7.6 最終アクセス時刻 (Last Accessed Times)

 

HttpSessionインターフェイスのgetLastAccessedTimeメソッドにより、サーブレットが現在の要求の前にこのセッションがアクセスされた最後の時刻を知ることが可能となる。このセッションは、このセッションの部分であるひとつの要求がサーブレット コンテキストにより処理されたとき、このセッションがアクセスされたと考えられる。

 

 

7.7 重要なセッションの意味 (Important Session Semantics)

 

 

7.7.1 スレッドの問題 (Threading Issues)

 

要求スレッドを処理中の複数のサーブレットが単一のセッション オブジェクトを同時にアクティブにアクセスする事があり得る。該セッションにストアされている資源をアクセスするときに必要とあらば同期化するのは開発者の責任である。

 

 

7.7.2 分散環境 (Distributed Environments)

 

配布可能とマークされたアプリケーション内では、あるセッションに属する総ての要求はある時刻においては単一のVMにより処理されている。加えて、setAttributeまたはputValueメソッドを使ってHttpSessionクラスのインスタンスに配置された総てのオブジェクトは、Serializableインターフェイスを実装しなければならない。非serializableオブジェクトを該セッションに配置されたときはサーブレット コンテナはIllegalArgumentException例外をスローする。

 

上記の制約は非分散コンテナで遭遇する以上に更なる並行処理の問題に遭遇はしないことが保証されることを意味する。加えて、コンテナの提供者は、セッション オブジェクトとそのコンテンツを分散システムのどのアクティブなノードから他のノードへ移動させる機能をもたせてスケーラビリティを確保することができる。

 

 

7.7.3 クライアントのセマンティクス (Client Semantics)

 

cookiesあるいはSSL認証は通常webブラウザのプロセスで処理され、そのブラウザの特定のウインドウとは関連図けられてはいないので、クライアントアプリケーションからサーブレットコンテナへの総てのウインドウからの要求は、同じセッションの部分である可能性がある。ポータビリティを最大とする為に、開発者はクライアントの総てのウインドウが同じセッションに参加しているものと仮定すべきである。