Oracle® Fusion Middleware Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発 12c (12.2.1.1.0) E77264-02 |
|
前 |
次 |
この章の内容は以下のとおりです。
セッション・トラッキングを使用すると、複数のサーブレットかHTMLページにわたって、本来はステートレスであるユーザーの状況を追跡できます。セッションとは、ある期間中に同じクライアントから出される一連の関連性のあるブラウザ・リクエストのことです。セッション・トラッキングは、ショッピング・カート・アプリケーションのように、全体としてなんらかの意味を持つ一連のブラウザ・リクエスト(これをページと見なす)を結合します。
WebLogic Serverは、デフォルトによってセッション・トラッキングを処理するよう設定されています。セッション・トラッキングを使用する際にプロパティを設定する必要はありません。ただし、WebLogic Serverがどのようにセッションを管理するかを構成することは、最高のパフォーマンスを実現するためにアプリケーションをチューニングするときの重要な鍵となります。セッション管理を設定するときは、次のような要素を決定します。
サーブレットをヒットする予定ユーザー数
各セッションの継続時間
各ユーザーに対する予定格納データ量
WebLogic Serverインスタンスに割り当てられるヒープ・サイズ
HTTPセッションのデータを永続的に格納することもできます。「セッションの永続性の構成」を参照してください。
WebLogic Serverのセッション・トラッキングは、WebLogic固有のデプロイメント記述子であるweblogic.xml
にプロパティを定義することによって構成します。セッション属性の全リストについては、「session-descriptor」を参照してください。
以前のリリースのWebLogic Serverでは、SessionIDの形式が変更されたことで、ロード・バランサがセッションの固定を保持できなくなっていました。サーバー起動フラグ(-Dweblogic.servlet.useExtendedSessionFormat=true
)に、ロード・バランシング・アプリケーションがセッションを固定するために必要な情報が保持されるようになりました。URLの書換えがアクティブになっていると、拡張されたセッションIDの形式はURLの一部になり、起動フラグがtrueに設定されます。
HTTPセッションが期限切れになるまでの間隔を指定できます。セッションが期限切れになると、そのセッションに格納されたデータは破棄されます。この間隔は、次のとおりweb.xml
またはweblogic.xml
に設定できます。
WebLogic固有のデプロイメント記述子であるweblogic.xml
のsession-descriptor
要素のtimeout-secs
パラメータ値を設定します。この値は秒単位で設定します。詳細は、「session-descriptor」を参照してください。
Java EE標準のWebアプリケーション・デプロイメント記述子web.xml
でsession-timeout
要素を設定します。
WebLogic Serverは、Cookieがクライアント・ブラウザによってサポートされる場合、Cookieを使用してセッション管理を行います。
WebLogic Serverがセッション・トラッキングに使用するCookieは、デフォルトによって一時的なものとして設定されているため、セッションより長く存続することはありません。ユーザーがブラウザを終了すると、Cookieは失われ、セッションが終了します。この動作はセッションの用途の基本であり、このようにセッションを使用することをお薦めします。
Cookieのセッション・トラッキング・パラメータは、WebLogic固有のデプロイメント記述子であるweblogic.xml
で構成できます。セッションとCookieに関連するパラメータの全リストについては、「session-descriptor」を参照してください。
長く存続するクライアント側のユーザー・データの場合、アプリケーションをプログラムして、HTTPサーブレットAPIによってブラウザ上で独自のCookieを作成して構成します。アプリケーションは、HTTPセッションに関連付けられたCookieを使用するよう試行しません。アプリケーションがCookieを使用して特定のマシンのユーザーの自動ログインを行う場合、新しいCookieの存続期間を長く設定します。Cookieは、クライアント・マシンだけから送ることができます。アプリケーションは、そのユーザーが複数の場所からアクセスする必要がある場合、サーバーにデータを格納する必要があります。
ブラウザCookieの存続期間を直接セッションの長さに関連付けることはできません。Cookieがそれに関連付けられているセッションより早く期限切れになった場合、そのセッションは切り離されてしまいます。セッションがそれに関連付けられているCookieより早く期限切れになった場合、サーブレットはそのセッションを見つけることができません。この場合、新しいセッションはrequest.getSession(true)
メソッドが呼び出されるときに自動的に割り当てられます。
Cookieの最大存続時間は、weblogic.xml
デプロイメント記述子のセッション記述子にあるcookie-max-age-secs
要素で設定できます。「session-descriptor」を参照してください。
ユーザー認証情報は、ユーザーのセッション・データと、Webアプリケーションのターゲットとなるサーバーまたは仮想ホストのコンテキストの両方に格納されます。ユーザーのログアウトに多く使われるsession.invalidate()
メソッドでは、ユーザーの現在のセッションのみが無効になり、ユーザーの認証情報は有効なまま、サーバーまたは仮想ホストのコンテキストに格納されます。サーバーまたは仮想ホストが1つのWebアプリケーションのみのホストである場合、実際にはsession.invalidate()
メソッドでユーザーをログアウトします。
複数のWebアプリケーションで認証を使用するときには、複数のJavaメソッドと方式を使用できます。詳細は、「セッションのログアウトと終了」を参照してください。
デフォルトでは、Webアプリケーション間で同じセッションが共有されることはありません。Webアプリケーション間で同じセッションを共有する場合は、weblogic-application.xml
デプロイメント記述子において、アプリケーション・レベルでセッション記述子を構成できます。Webアプリケーション間で同じセッションを共有するには、weblogic-application.xml
デプロイメント記述子内で、セッション記述子のsharing-enabled
属性をtrue
に設定します。「session-descriptor」の「sharing-enabled」を参照してください。
アプリケーション・レベルで指定したセッション記述子の構成は、アプリケーション内のすべてのWebアプリケーションについて、Webアプリケーション・レベルで指定したすべてのセッション記述子構成をオーバーライドします。Webアプリケーション・レベルでsharing-enabled
属性をtrueに設定しても、これは無視されます。
アプリケーション内のすべてのWebアプリケーションは、次の例のようにweblogic-application.xml
デプロイメント記述子内でセッション記述子を指定して、sharing-enabled
属性をtrue
に設定した場合、同じセッション・インスタンスを使用して自動的に起動されます。
<?xml version="1.0" encoding="ISO-8859-1"?> <weblogic-application xmlns="http://xmlns.oracle.com/weblogic/weblogic-application";;> ... <session-descriptor> <persistent-store-type>memory</persistent-store-type> <sharing-enabled>true</sharing-enabled> ... </session-descriptor> ... </weblogic-application>
セッションの永続性を使用して、HTTPセッション・オブジェクトにデータを永続的に格納し、WebLogic Serverのクラスタ全体のフェイルオーバーとロード・バランシングを有効にします。アプリケーションがHTTPセッション・オブジェクトにデータを格納するとき、データをシリアライズ可能にする必要があります。
次のセッション永続性の実装がサポートされています。
メモリー(単一サーバー、非レプリケート)
ファイル・システムの永続性
JDBCの永続性
Cookieベースの永続性
WebLogic ServerクラスタまたはCoherenceクラスタのいずれかを使用するインメモリー・レプリケーション
最初の4つについてはここで説明します。インメモリー・レプリケーションの詳細は、『Oracle WebLogic Serverクラスタの管理』のHTTPセッション状態のレプリケーションに関する項を参照してください。セッション状態のレプリケーションのためのCoherenceの使用の詳細は、『Oracle Coherence*WebでのHTTPセッション・マネージメントの管理』を参照してください。
ファイル、JDBC、Cookieベース、およびメモリー(単一サーバー、非レプリケート)のセッション永続性には、共通のプロパティがいくつか存在します。以次の項で説明するとおり、各永続性メソッドはそれぞれ独自の構成可能なパラメータ・セットを持っています。これらのパラメータは、weblogic.xml
デプロイメント記述子ファイルのsession-descriptor
要素の下位要素です。
この項では、ファイル・ベースの永続性とJDBCベースの永続性に共通するパラメータについて説明します。weblogic.xml
デプロイメント記述子ファイルのsession-descriptor
要素で次のパラメータを定義することにより、メモリー内に保持されるセッション数を構成できます。これらのパラメータは、セッション永続性を使用している場合にのみ適用できます。
cache-size
- メモリー内で一度にアクティブにできるキャッシュしたセッションの数を制限します。同時に大量のアクティブ・セッションが予想される場合、仮想メモリーとのスワップにより、パフォーマンスが低下する可能性があるため、これらのセッションでサーバーのRAMを取り込む必要はありません。キャッシュがいっぱいになった場合、最低使用頻度セッションは永続ストアに格納され、必要に応じて自動的にリコールされます。永続性を使用しない場合、このプロパティは無視され、メイン・メモリーに許可されるセッションの数にソフト制限はありません。デフォルトでは、キャッシュしたセッションの数は1028です。キャッシュをオフにするには、この数を0に設定します。session-descriptorのcache-sizeに関する項を参照してください。
注意:
cache-size
は、JDBCおよびファイル・ベースのセッションによって、インメモリー・バブル・キャッシュを保持する目的にのみ使用されます。他の永続性タイプには適用されません。
invalidation-interval-secs
は、タイムアウトの無効なセッションに対してハウスクリーニング・チェックを実行してから古いセッションを削除してメモリーを解放するまでWebLogicサーバーが待機する時間(秒)を設定します。この要素を使用して、トラフィックの多いサイトでWebLogic Serverのパフォーマンスが最適化されるようにチューニングします。session-descriptorの「invalidation-interval-secs」を参照してください。
最小値は毎秒(1)です。最大値は、週に1回(604,800秒)です。この属性を設定しない場合、デフォルトは60秒になります。
メモリー・ベースのストレージを使用する場合、すべてのセッション情報はメモリーに格納され、WebLogic Serverを終了して再起動すると失われます。メモリー・ベース、単一サーバー、非レプリケート永続ストレージを使用するには、weblogic.xml
デプロイメント記述子ファイルのsession-descriptor
要素にあるpersistent-store-type
パラメータをmemory
に設定します。「session-descriptor」を参照してください。
注意:
WebLogic Serverを実行するときに十分なヒープ・サイズを割り当てないと、負荷がかかったときにサーバーのメモリーが足りなくなることがあります。
ファイル・ベースの永続ストレージをセッション用に構成するには:
デプロイメント記述子ファイルweblogic.xml
で、session-descriptor
要素内のpersistent-store-type
パラメータをfile
に設定します。『session-descriptor』の「persistent-store-type」を参照してください。
WebLogic Serverがセッションを格納するディレクトリを設定します。session-descriptorの「persistent-store-dir」を参照してください。
注意:
このディレクトリは作成する必要があります。また、適切なアクセス権限がディレクトリに割り当てられていることを確認します。
JDBCの永続性は、この目的のために提供されたスキーマを使ってデータベース表にセッション・データを格納します。JDBCドライバを備えたデータベースはすべて使用できます。データベース・アクセスは、接続プールを使って構成します。
JDBCセッションの永続性を利用している場合、WebLogic Serverはシステム時間を使用してセッションのセッション・ライフ時間を判別するため、同じクラスタ内でサーバーが実行されているすべてのマシン上のシステム・クロックを同期する必要があります。
JDBCベースの永続ストレージをセッション用に構成するには:
weblogic.xml
デプロイメント記述子ファイルのsession-descriptor
要素にあるpersistent-store-type
パラメータをjdbc
に設定します。「session-descriptor」を参照してください。
weblogic.xml
デプロイメント記述子ファイルのsession-descriptor
要素にあるpersistent-store-pool
またはpersistent-data-source-jndi-name
パラメータを使用して、永続ストレージに使用されるJDBC接続プールを設定します。WebLogic Server 管理コンソールで定義される接続プールの名前を使用します。「session-descriptor」を参照してください。
アプリケーションまたはWebアプリケーションのHTTPセッションの非同期JDBC永続性では、persistent-store-pool
パラメータは無視されます。async-jdbc
ベースの永続性のためにJDBC接続プールを設定するには、weblogic.xml
デプロイメント記述子ファイルでsession-desciptor
要素のpersistent-data-source-jndi-name
パラメータを指定する必要があります。「session-descriptor」を参照してください。
JDBCベースの永続性のためのwl_servlet_sessions
というデータベース表を設定します。データベースに接続する接続プールは、この表の読取り/書込みアクセス権を保有する必要があります。
注意:
データベースで自動的に作成されない場合は、wl_id
およびwl_context_path
に索引を作成します。一部のデータベースでは、主キーの索引が自動的に作成されます。
列名とデータ型を次のように設定します。
表10-1 wl_servlet_sessionsの作成
列名 | データ型 |
---|---|
wl_id |
最大100文字の可変長の英数字列。例: Oracle 主キーは次のように設定します。
|
wl_context_path |
最大100文字の可変長の英数字列; 例: Oracle VARCHAR2(100)。この列は主キーの一部として使用します。( |
wl_is_new |
1文字の列。例: Oracle |
wl_create_time |
20桁の数値列。例: Oracle |
wl_is_valid |
1文字の列。例: Oracle |
wl_session_values |
ラージ・バイナリ・列。例: Oracle |
wl_access_time |
20桁の数値列。例: |
wl_max_inactive_interval |
整数列。例: Oracle |
Oracle DBMSを使用している場合、次のSQL文を使ってwl_servlet_sessions
表を作成できます。このSQL文をユーザーのDBMSにあわせて変更します。
例10-1 Oracle DBMSを使用したwl_servlet_sessions表の作成
create table wl_servlet_sessions ( wl_id VARCHAR2(100) NOT NULL, wl_context_path VARCHAR2(100) NOT NULL, wl_is_new CHAR(1), wl_create_time NUMBER(20), wl_is_valid CHAR(1), wl_session_values LONG RAW, wl_access_time NUMBER(20), wl_max_inactive_interval INTEGER, PRIMARY KEY (wl_id, wl_context_path) );
例10-2 SqlServer 2000を使用したwl_servlet_sessions表の作成
SqlServer2000を使用している場合、次のSQL文を使ってwl_servlet_sessions
表を作成できます。このSQL文をユーザーのDBMSにあわせて変更します。
create table wl_servlet_sessions ( wl_id VARCHAR2(100) NOT NULL, wl_context_path VARCHAR2(100) NOT NULL, wl_is_new VARCHAR(1), wl_create_time DECIMAL, wl_is_valid VARCHAR(1), wl_session_values IMAGE, wl_access_time DECIMAL, wl_max_inactive_interval INTEGER, PRIMARY KEY (wl_id, wl_context_path) );
例10-3 DB2を使用したwl_servlet_sessions表の作成
DB2を使用している場合、次のSQL文を使ってwl_servlet_sessions
表を作成できます。このSQL文をユーザーのDBMSにあわせて変更します。
CREATE TABLE WL_SERVLET_SESSIONS ( WL_ID VARCHAR(100) not null, WL_CONTEXT_PATH VARCHAR(100) not null, WL_IS_NEW SMALLINT, WL_CREATE_TIME DECIMAL(16), WL_IS_VALID SMALLINT, wl_session_values BLOB(10M) NOT LOGGED, WL_ACCESS_TIME DECIMAL(16), WL_MAX_INACTIVE_INTERVAL INTEGER, PRIMARY KEY (WL_ID,WL_CONTEXT_PATH) );
Sybaseを使用している場合、次のSQL文を使ってwl_servlet_sessions
表を作成できます。このSQL文をユーザーのDBMSにあわせて変更します。
例10-4 Sybaseを使用したwl_servlet_sessions表の作成
create table WL_SERVLET_SESSIONS ( WL_ID varchar(100) not null , WL_CONTEXT_PATH varchar(100) not null , WL_IS_NEW CHAR(1) null , WL_CREATE_TIME decimal(16,0) null , WL_IS_VALID CHAR(1) null , WL_SESSION_VALUES image null , WL_ACCESS_TIME decimal(16,0) null , WL_MAX_INACTIVE_INTERVAL int null , ) go alter table WL_SERVLET_SESSIONS add PRIMARY KEY CLUSTERED (WL_ID, WL_CONTEXT_PATH) go
WebLogic Serverは、リクエストが読取り専用の場合は、HTTPセッション状態をディスクに書き込みません。つまりリクエストによってHTTPセッションに変更が加えられることはありません。セッションがアクセスされると、データベース内ではwl_access_time
列のみが更新されます。
読取り専用でないリクエストの場合、Webアプリケーション・コンテナは、HTTPリクエストのたびに、セッション状態の変更についてデータベースを更新します。これが行われるのは、クラスタ内のすべてのサーバーが、フェイルオーバーに際してリクエストを処理し、データベースから最新のセッション状態を取得できるようにするためです。
複数のデータベース・問合せが生じることを回避するため、WebLogic Serverでは最近使用されたセッションがキャッシュされます。最近使用されたセッションは、リクエストごとにデータベースからリフレッシュされることはありません。キャッシュ内のセッション数は、WebLogic Server固有のデプロイメント記述子weblogic.xml
のsession-descriptor
要素内のcache-size
パラメータによって規定されます。「session-descriptor」を参照してください。
Cookieベースのセッション永続性は、ユーザーのブラウザのCookieにすべてのセッション・データを格納することで、セッション永続性のステートレスなソリューションを提供します。Cookieベースのセッション永続性が最も役に立つのは、セッションに大量のデータを格納する必要がないときです。Cookieベースのセッション永続性は、クラスタ・フェイルオーバー・ロジックが必要ないので、WebLogic Serverのインストール環境をより簡単に管理できます。セッションが格納されるのはブラウザ内であって、サーバー上ではありません。WebLogic Serverの起動と停止は、セッションを失わずに行うことができます。
Cookieベースのセッション永続性には、次に示すいくつかの制限事項があります。
セッションに格納できるのは文字列属性のみです。セッションに他の種類のオブジェクトを格納した場合、IllegalArgument
例外がスローされます。
HTTPレスポンスはフラッシュできません(Cookieはレスポンスが発行される前にヘッダー・データに書き込まれる必要があるため)。
レスポンスのコンテンツの長さがバッファ・サイズを超える場合、レスポンスは自動的にフラッシュされ、セッション・データはCookie内では更新できません。バッファ・サイズはデフォルトで8192バイトです。バッファ・サイズはjavax.servlet.ServletResponse.setBufferSize()メソッドで変更できます。
使用できる認証は基本的なもの(ブラウザ・ベース)のみです。
セッション・データはクリア・テキストでブラウザに送信されます。
ユーザーのブラウザを、Cookieを受け付けるように構成する必要があります。
Cookieベースのセッション永続性を使用する場合、文字列でカンマ(,)を使用することはできません。これに従わない場合は例外が発生します。
Cookieベースのセッション永続性を設定するには:
weblogic.xml
デプロイメント記述子ファイルのsession-descriptor
要素にあるpersistent-store-type
パラメータをcookie
に設定します。「session-descriptor」を参照してください。
必要な場合は、persistent-store-cookie-name
要素を使ってCookieに名前を設定します。デフォルトはWLCOOKIE
です。「session-descriptor」を参照してください。
状況によっては、ブラウザまたは無線デバイスがCookieを受け入れないこともあります。この場合、Cookieによるセッション・トラッキングを行うことができません。URL書換えを使用すると、ブラウザがCookieを受け入れないことをWebLogic Serverが検出したときに、こうした状況を自動的に置き換えることができます。URL書換えでは、セッションIDをWebページのハイパーリンクにエンコードし、サーブレットはそれらをブラウザに送り返します。ユーザーが以後これらのリンクをクリックすると、WebLogic ServerはURLアドレスからそのIDを抽出し、サーブレットがgetSession()
メソッドを呼び出すと適切なHttpSession
を見つけ出します。
WebLogic固有のデプロイメント記述子であるweblogic.xml
のsession-descriptor
要素にurl-rewriting-enabled
パラメータを設定することで、URL書換えを有効にします。
この属性のデフォルト値はtrue
です。「session-descriptor」を参照してください。
URL書換えのサポートに関するガイドライン
次に示すように、URLを出力ストリームに直接書き出すことは避けます。
out.println("<a href=\"/myshop/catalog.jsp\">catalog</a>");
かわりに、HttpServletResponse.encodeURL()
メソッドを使用します。例:
out.println("<a href=\" + response.encodeURL("myshop/catalog.jsp") + "\">catalog</a>");
encodeURL()
メソッドを呼び出すと、URLを書き換える必要があるかどうかが調べられます。書換えが必要な場合、WebLogic Serverは、セミコロンで始まるセッションIDをURLに追加することによって、URLを書き換えます。
WebLogic Serverへのレスポンスとして返されるURLに加えて、リダイレクトを送信するURLをエンコードします。例:
if (session.isNew()) response.sendRedirect (response.encodeRedirectUrl(welcomeURL));
WebLogic Serverはセッションが新しいときには、ブラウザがCookieを受け入れる場合でもURL書換えを使用します。これは、セッションの最初ではサーバーはブラウザがCookieを受け入れるかどうかを判断できないからです。
プラグイン(Apache、NSAPI、ISAPI、HttpClusterServlet
、またはHttpProxyServlet
)を使用しており、バックエンド・サーバーでURL書換え(response.sendRedirect(url)
またはresponse.encodeRedirectURL(url)
)を使用している場合は、一定の条件を満たすと、URLにPathTrim
パラメータとPathPrepend
パラメータの両方が適用されます。一定の条件とは、「PathPrepend
がnullであるか、PathPrepend
がすでに適用されている」というもので、PathTrim
はこのいずれかを満たす場合にのみ適用されます。
サーブレットは、HttpServletRequest.isRequestedSessionIdFromCookie()
メソッドから返されるブール値をチェックすることによって、特定のセッションIDがCookieから受け取られたかどうかを確認できます。rアプリケーションは適切に応答するか、または、WebLogic ServerによるURL書換えに依存します。
注意:
CISCO Local Directorロード・バランサでは、疑問符"?
"がURLの書換えのデリミタとして想定されています。WebLogic ServerのURLの書換えメカニズムではデリミタとしてセミコロン(;)を使用するため、WebLogic Serverの書換えとこのロード・バランサの間には互換性がありません。
WAPアプリケーションを作成する場合、WAPプロトコルはCookieをサポートしていないため、URLを書き換える必要があります。また、一部のWAPデバイスでは、URLの長さが128文字(属性も含む)に制限されます。これにより、URL書換えによって転送できるデータ・サイズが制限されます。属性用の領域を大きくするために、WebLogic Serverでランダムに生成されるセッションIDのサイズを制限できます。
WAPEnabled
属性を使用するには、WebLogic Server管理コンソールの「サーバー」→「プロトコル」→「HTTP」→「詳細オプション」で指定します。WAPEnabled
属性を使用すると、セッションIDのサイズが52文字までに制限され、!
および#
などの特殊文字の使用が禁止されます。weblogic.xml
のIDLengthパラメータを使用して、セッションIDのサイズをさらに制限することもできます。詳細は、session-descriptorの「id-length」を参照してください。
注意:
WebLogic Server固有のデプロイメント記述子であるweblogic.xml
でsession-descriptor
要素のid-length
下位要素に32未満の値が含まれている場合、WebLogic Serverでは値が自動的に32に上げられ、次のメッセージが表示されます。
The IDLength is too short. It is not secure. WLS will raise the length to 32.
セッション・トラッキングを使用すると、複数のサーブレットかHTMLページにわたって、本来はステートレスであるユーザーの状況を追跡できます。セッションとは、ある期間中に同じクライアントから出される一連の関連性のあるブラウザ・リクエストのことです。セッション・トラッキングは、ショッピング・カート・アプリケーションのように、全体としてなんらかの意味を持つ一連のブラウザ・リクエスト(これをページと見なす)を結合します。
次の項では、HTTPサーブレットからのセッション・トラッキングについて、様々な観点から説明します。
セッション・トラッキングという概念が発展する前は、ページの非表示フィールドに情報を詰め込むか、長い文字列をリンクで使われるURLに追加してユーザーの選択内容を埋め込むことで、ページに状態を組み込んでいました。このよい例が、サーチ・エンジン・サイトです。サーチ・エンジン・サイトの多くはいまだにCGIに依存しています。これらのサイトは、URLの後にHTTPで予約されている?
記号を付け、その後に続くURLパラメータの名前=値のペアを使用して、ユーザーの選択を追跡します。このようにすると、URLは非常に長いものになることがあり、CGIスクリプトはこれを慎重に解析し、管理する必要があります。この手法の問題点は、情報をセッションからセッションへと渡せないことです。URLの制御を失うと、つまりユーザーがページから離れると、ユーザー情報は永久に失われます。
その後、NetscapeはブラウザのCookieを導入しました。これを使用してサーバーごとにクライアント上のユーザー関連情報を格納することができます。しかし、ブラウザによってはまだCookieを完全にサポートしていないものもあり、またブラウザのCookieオプションをオフにしておくことを選ぶユーザーもいます。もう1つの考慮すべき要因は、ほとんどのブラウザではCookieで格納できるデータ量を制限しているということです。
CGIの手法とは異なり、HTTPサーブレットの仕様では、サーバーがサーバー上のユーザーの詳細情報を単一のセッションを超えて格納できる方法が定義されており、セッションのトラッキングによるコードの複雑化を避けることが可能です。サーブレットを使用すると、HttpSessionオブジェクトによって単一のセッションを超える範囲でユーザー入力を追跡し、セッションの詳細を複数のサーブレットで共有できます。セッション・データは、WebLogicサービスで使用できる様々なメソッドを使用して保持することができます。
WebLogicが実装してサポートしているJava Servlet APIでは、各サーブレットはHttpSession
オブジェクトを使用して、サーバー側セッションにアクセスすることができます。HttpServletRequest
オブジェクトを使用して、サーブレットのservice()
メソッド内のHttpSession
オブジェクトにアクセスできます。次の例のように変数request
を使用します。
HttpSession session = request.getSession(true);
引数true
でrequest.getSession(true)
メソッドが呼び出されると、そのクライアントに対して既存のHttpSession
オブジェクトがない場合には、HttpSessionオブジェクトが生成されます。セッション・オブジェクトは、そのセッションの存続期間の間WebLogic Serverに存在し、そのクライアントに関連した情報を蓄積します。サーブレットは、必要に応じて、セッション・オブジェクトで情報の追加や削除を行います。セッションは特定のクライアントに関連付けられます。クライアントがサーブレットを訪れると、毎回、getSession()
メソッドが呼び出されたときに関連する同じHttpSession
オブジェクトが取得されます。
HttpSession
でサポートされるメソッドの詳細は、http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.html
のHttpServlet APIを参照してください。
次の例では、service()
メソッドが、セッション中にユーザーがサーブレットをリクエストする回数を数えます。
public void service(HttpServletRequest request, HttpServletResponse, response) throws IOException { // Get the session and the counter param attribute HttpSession session = request.getSession (true); Integer ival = (Integer) session.getAttribute("simplesession.counter"); if (ival == null) // Initialize the counter ival = new Integer (1); else // Increment the counter ival = new Integer (ival.intValue () + 1); // Set the new attribute value in the session session.setAttribute("simplesession.counter", ival); // Output the HTML page out.print("<HTML><body>"); out.print("<center> You have hit this page "); out.print(ival + " times!"); out.print("</body></html>"); }
セッションは、1つのトランザクションの一連のページにわたるユーザーの選択を追跡します。1つのトランザクションは、ある品物を閲覧し、それをショッピング・カートに追加した後、支払手続きをするといった複数のタスクで構成されます。セッションは永続的なものではなく、以下のいずれかの時点で、その存続期間は終了します。
ユーザーがサイトを離れ、ブラウザがCookieを受け入れない場合。
ユーザーがブラウザを終了した場合。
動作がないため、セッションがタイムアウトになった場合。
セッションが完了し、サーブレットによって無効にされた場合。
ユーザーがログアウトし、サーブレットによって無効にされた場合。
より永続的に長時間データを保存するには、サーブレットでJDBCまたはEJBを使用して詳細をデータベースに書き込み、存続期間が長いCookieやユーザー名とパスワードによって、そのデータとクライアントとを関連付ける必要があります。
注意:
このドキュメントでは、セッションが内部的にCookieや永続性を使用すると説明していますが、セッションをユーザーに関するデータ格納のための一般的なメカニズムとして使用してはいけません。
WebLogic Serverでは、各クライアントにどのセッションが関連付けられているのかが、どのようにして認識されるのでしょうか。HttpSession
がサーブレットで生成されると、一意のIDと関連付けられます。ブラウザは、このセッションIDをそのリクエストに付与し、サーバーが再びセッション・データを見つけられるようにする必要があります。サーバーは、クライアントにCookieを設定することによって、このIDを保存しようとします。一度Cookieが設定されると、ブラウザがサーバーにリクエストを送るたびに、リクエストにはそのIDを内包したCookieが含まれます。サーバーは自動的にCookieを解析し、サーブレットがgetSession()
メソッドを呼び出すと、セッション・データを提供します。
クライアントがCookieを受け入れない場合、代わりの方法としては、クライアントへ送り返されるページの中で、URLリンクにそのIDをエンコードするしかありません。このため、サーブレットのレスポンスにURLを入れる場合は、必ずencodeURL()
メソッドを使用します。WebLogic ServerはブラウザがCookieを受け入れるかどうかを検出して、不必要なURLのエンコードは行いません。自動的に、エンコードされたURLからセッションIDを解析し、getSession()
メソッドを呼び出すと、正しいセッション・データを取得します。encodeURL()
メソッドを使用すると、セッション・トラッキングにどの手順を使用しても、サーブレットのコードが破壊されることはありません。詳細は、「Cookieに代わるURL書換えの使用」を参照してください。
getSession(true)
メソッドを使用してセッションを取得した後、HttpSession.isNew()
メソッドを呼び出すことにより、そのセッションが生成されたばかりかどうかがわかります。このメソッドがtrue
を返した場合、クライアントはまだ有効なセッションを持っておらず、またこの時点では新規のセッションを認識しません。クライアントが新規のセッションを認識するのは、サーバーからレスポンスがポストされて戻ってからです。
ビジネス・ロジックに合った方法で、新規または既存のセッションに適応するようにアプリケーションを設計してください。たとえば、セッションがまだ開始していないと判断すれば、次のサンプル・コードのように、アプリケーションでクライアントのURLをログイン/パスワードのページにリダイレクトしてもよいでしょう。
HttpSession session = request.getSession(true); if (session.isNew()) { response.sendRedirect(welcomeURL); }
ログインのページでは、システムにログインするか、新規アカウントを作成するかを選択できます。また、Java EE標準のWebアプリケーション・デプロイメント記述子web.xml
のlogin-config
要素を使用して、Webアプリケーションでログイン・ページを指定することもできます。
名前=値のペアを使用して、HttpSession
オブジェクトにデータを格納できます。セッションに格納されたデータは、そのセッションを通じて利用することができます。セッションにデータを格納するには、次のメソッドをHttpSession
インタフェースから使用します。
getAttribute()
getAttributeNames()
setAttribute()
removeAttribute()
The following code fragment shows how to get all the existing name=value pairs:
Enumeration sessionNames = session.getAttributeNames();
String sessionName = null;
Object sessionValue = null;
while (sessionNames.hasMoreElements()) {
sessionName = (String)sessionNames.nextElement();
sessionValue = session.getAttribute(sessionName);
System.out.println("Session name is " + sessionName +
", value is " + sessionValue);
}
名前の付いた属性を追加または上書きするには、setAttribute()
メソッドを使用します。名前の付いた属性を完全に削除するには、removeAttribute()
メソッドを使用します。
注意:
JavaのObject
の子孫をセッション属性として追加し、それに名前を関連付けることができます。ただし、セッション永続性を利用している場合、属性値オブジェクトはjava.io.Serializable
を実装する必要があります。
アプリケーションがデリケートな情報を扱う場合は、セッションからログアウトする機能の提供を検討します。これは、ショッピング・カートやインターネットの電子メール・アカウントを使用する際には一般的な機能です。同一のブラウザがサービスに戻るとき、ユーザーはシステムにログインし直さなければなりません。
ユーザー認証情報は、ユーザーのセッション・データと、Webアプリケーションのターゲットとなるサーバーまたは仮想ホストのコンテキストの両方に格納されます。ユーザーのログアウトに多く使われるsession.invalidate()
メソッドでは、ユーザーの現在のセッションのみが無効になり、ユーザーの認証情報は有効なまま、サーバーまたは仮想ホストのコンテキストに格納されます。サーバーまたは仮想ホストが1つのWebアプリケーションのみをホストしている場合は、session.invalidate()
メソッドを実行するとユーザーはログアウトされます。
session.invalidate()
を呼び出した後、無効にされたセッションを参照しないでください。参照した場合、IllegalStateException
がスローされます。ユーザーが次に同じブラウザからサーブレットにアクセスしたときには、セッション・データは失われています。getSession(true)
メソッドを呼び出すと、新しいセッションが作成されます。この時点で、ユーザーに再度ログイン・ページを送信できます。
サーバーまたは仮想ホストが複数のWebアプリケーションによって割り当てられている場合、すべてのWebアプリケーションからユーザーをログアウトするには、別の方法が必要になります。サーブレット仕様では、すべてのWebアプリケーションからユーザーをログアウトするためのAPIが用意されていないため、次のメソッドを使用します。
weblogic.servlet.security.ServletAuthentication.logout()
- 認証データをユーザーのセッション・データから削除します。これにより、ユーザーはログアウトされますが、セッションは引き続き有効です。
weblogic.servlet.security.ServletAuthentication.invalidateAll()
- すべてのセッションを無効にして、現在のユーザーの認証データを削除します。Cookieも無効になります。
weblogic.servlet.security.ServletAuthentication.killCookie()
- レスポンスがブラウザに送信された直後に有効期限が切れるようにCookieを設定して、現在のCookieを無効にします。このメソッドでは、レスポンスがユーザーのブラウザに正常に届く必要があります。セッションはタイムアウトするまで維持されます。
シングル・サインオンへの参加からWebアプリケーションを除外するには、除外するWebアプリケーションに異なるCookie名を定義します。詳細は、「WebLogic ServerセッションCookieの構成」を参照してください。
WebLogic Serverでは、セッション・トラッキングの処理方法を決定する様々な属性を構成できます。これらのセッション・トラッキング属性の構成の詳細は、「session-descriptor」を参照してください。
状況によっては、ブラウザがCookieを受け入れないこともあります。この場合、Cookieによるセッション・トラッキングができません。代わりにURL書換えを使用すると、ブラウザがCookieを受け入れないことをWebLogic Serverが検出したときに、こうした状況を自動的に置き換えることができます。URL書換えでは、セッションIDをWebページのハイパーリンクにエンコードし、サーブレットはそれらをブラウザに送り返します。ユーザーが以後これらのリンクをクリックすると、WebLogic ServerはURLからそのIDを抽出し、適切なHttpSession
を見つけます。次に
getSession()
メソッドを使用してセッション・データにアクセスします。
WebLogic ServerでURL書換えを有効にするには、WebLogic Server固有のデプロイメント記述子weblogic.xml
のsession-descriptor
要素でURL-rewriting-enabled
パラメータをtrue
に設定します。「session-descriptor」を参照してください。
URL書換えをサポートするために、コードでURLを適切に処理するには、以下のガイドラインに従います。
次に示すように、URLを出力ストリームに直接書き出すことは避けます。
out.println("<a href=\"/myshop/catalog.jsp\">catalog</a>");
かわりに、HttpServletResponse.encodeURL()
メソッドを使用します。例:
out.println("<a href=\"" + response.encodeURL("myshop/catalog.jsp") + "\">catalog</a>");
encodeURL()
メソッドを呼び出すと、URLを書き換える必要があるかどうかが調べられます。必要である場合、URLにセッションIDを組み込むことによって書換えを行います。
WebLogic Serverへのレスポンスとして返されるURLに加えて、リダイレクトを送信するURLをエンコードします。例:
if (session.isNew()) response.sendRedirect(response.encodeRedirectUrl(welcomeURL));
WebLogic Serverはセッションが新しいときには、ブラウザがCookieを受け入れる場合でもURL書換えを使用します。これは、セッションの最初ではサーバーはブラウザがCookieを受け入れるかどうかを判断できないからです。
サーブレットは、HttpServletRequest.isRequestedSessionIdFromCookie()
メソッドから返されるブール値をチェックすることによって、所定のセッションがCookieから返されたかを確認できます。アプリケーションは適切に応答するか、WebLogic ServerによるURL書換えに依存します。
注意:
CISCO Local Directorロード・バランサでは、疑問符"?
"がURLの書換えのデリミタとして想定されています。WebLogic ServerのURLの書換えメカニズムはデリミタとしてセミコロン";
"を使用するため、WebLogic Serverの書換えとこのロード・バランサの間には互換性がありません。
WAPアプリケーションを作成する場合、WAPプロトコルはCookieをサポートしていないため、URLを書き換える必要があります。また、一部のWAPデバイスでは、URLの長さが128文字(パラメータも含む)に制限されます。これにより、URL書換えによって転送できるデータ・サイズが制限されます。パラメータ用に使えるスペースを増やすには、WebLogic Server固有のデプロイメント記述子weblogic.xml
のsession-descriptor
要素でid-length
パラメータを使用してバイト数を指定し、WebLogic Serverによってランダムに生成されるセッションIDのサイズを制限できます。「session-descriptor」を参照してください。
最小値は32バイト、デフォルト値は52バイト、最大値はInteger.MAX_VALUE
です。(「URL書換えとWireless Access Protocol (WAP)」の注意を参照してください。)
WebLogic Serverは、セッション・データを永続ストレージに記録するように設定できます。セッション永続性を使用すると、以下の特性を利用できます。
フェイルオーバーのよさ。サーバーに障害が発生してもセッションが保存されるためです。
ロード・バランシングのよさ。どのサーバーでも、セッションがいくつあってもそのリクエストを処理し、キャッシュを使用して、パフォーマンスを最適化できるためです。詳細については、「セッションの永続性の構成」でcache-size
プロパティを参照してください。
セッションを、クラスタリングされたWebLogic Server間で共有できます。WebLogicクラスタではセッション永続性は必要条件ではなくなりました。そのかわりに、状態のインメモリー・レプリケーションを使用できます。詳細は、『Oracle WebLogic Serverクラスタの管理』を参照してください。
顧客が最高品質のサーブレット・セッション永続性を求めている場合は、JDBCベースの永続性が最適。セッション永続性はある程度犠牲にしても、パフォーマンスを大幅に高めたい顧客の場合には、インメモリー・レプリケーションが適切な選択です。JDBCベースの永続性は、インメモリー・レプリケーションよりも著しく低速です。サーブレット・セッションに対して、インメモリー・レプリケーションがJDBCベースの永続性よりも8倍高いパフォーマンスを提供したケースもあります。
どの種類のJavaオブジェクトでもセッションに入れることができますが、ファイル、JDBC、およびインメモリー・レプリケーションに関しては、java.io.Serializable
であるオブジェクトのみがセッションに格納されます。詳細は、「セッションの永続性の構成」を参照してください。
セッション永続性を、セッション間の長期データを格納する目的には使わないでください。つまり、後日クライアントがサイトに戻ったときに、アクティブなままのセッションがあっても、それに依存してはいけません。むしろアプリケーションでは、長期にわたる情報や重要な情報は、データベースの中に記録すべきです。
セッションはCookieのコンビニエンス・ラッパーではありません。セッションには長期間であろうと一定期間であろうと、クライアント・データを格納しようとしてはいけません。それよりも、アプリケーションのほうでCookieをブラウザ上に作成し設定すべきです。例として、Cookieが長期間存続できる自動ログイン機能、Cookieが短期間で失効する自動ログアウト機能などがあります。この場合、HTTPセッションを使用しないでください。かわりに、アプリケーション固有のロジックを記述します。
永続セッションを使用する場合、セッションに追加するすべての属性値オブジェクトは
java.io.Serializable
を実装する必要があります。
独自のシリアライズ可能なクラスを永続セッションに加える場合は、クラスの各インスタンス変数もシリアライズ可能になっているかに注意してください。そうでない場合は、それをtransient
として宣言できます。transient
にするべきインスタンス変数の一般的な例の1つは、HttpSession
オブジェクトです。(「セッションの永続化」の、セッションにおけるシリアライズされたオブジェクトの使用に関する注意を参照してください。)
HttpServletRequest
属性、ServletContext
属性、およびHttpSession
属性は、WebLogic ServerインスタンスがWebアプリケーション・クラスローダーで変更を検出するとシリアライズされます。クラスローダーは、Webアプリケーションが再デプロイされた場合、サーブレットで動的な変更があった場合、またはWebアプリケーション間で転送またはインクルードがあった場合に変更されます。
サーブレットの動的な変更時に属性がシリアライズされないようにするには、weblogic.xml
でservlet-reload-check-secs
を無効にします。Webアプリケーション間のディスパッチやWebアプリケーションの再デプロイメントの場合、属性のシリアライゼーションを回避する方法はありません。「servlet-reload-check-secs」を参照してください。
新しいセッションが作成され続けているのに、インメモリー・サーブレット・セッションの使用を構成することができなければ、サーバーはやがて、メモリー不足をスローします。これを回避するため、WebLogic Serverでは作成されるセッション数に対して、構成可能な制限を設けています。この数を超えると、新しいセッションの作成が試行されるたびに、weblogic.servlet.SessionCreationException
が発生します。この機能は、レプリケートされたインメモリー・セッションと、レプリケートされないインメモリー・セッションの双方に適用されます。
制限されたインメモリー・サーブレット・セッションの使用を構成するには、weblogic.xml
デプロイメント記述子のmax-in-memory-sessions
要素で、制限を設定します。「session-descriptor」を参照してください。
メモリーが過負荷になると、すべてのgetSession(true)
の試行に対して、weblogic.servlet.SessionCreationException (RuntimeException)
が発生します。サーブレット開発者は、次のようにしてこの例外に対処します。
例外発生時に、ユーザーに状況を説明する適切なエラー・メッセージを戻します。
Java EE標準のWebアプリケーション・デプロイメント記述子web.xml
で、weblogic.servlet.SessionCreationException
をエラー・ページにマップします。
デフォルトでは、メモリー過負荷保護は無効になっています。これはドメイン・レベルのフラグで有効化できます。
weblogic.management.configuration.WebAppContainerMBean.OverloadProtectionEnabled