HTTP はステートレスプロトコルです。Web サーバは、リクエストを受け取ってレスポンスを返すと、クライアントとの接続を終了します。Web サーバにはクライアントの情報は維持されません。そのため、同じクライアントから別のリクエストがきても、そのことを判断できません。Web サイトからクライアントやナビゲーションを自動追跡できないために、Web サイトで複雑なトランザクションを実行することが難しくなっています。
ただし、JRun では session オブジェクトがサポートされており、これを使用すれば、Web サーバとの対話全体を通してユーザーを追跡できます。session オブジェクトを使用して、ショッピングするユーザーを追跡し、登録情報や環境設定情報を送ることができます。また、サイトに接続するたびに情報を再入力する手間からユーザーを解放することもできます。
session オブジェクトは、特定のユーザーセッションに関する情報を保管します。デフォルトでは、JRun は Cookie を使用してセッションを追跡しますが、JRun では URL 書き換え、Hidden フォームフィールドやカスタムメソッドを使用してもセッションを追跡できます。Cookie 自体に セッション ID と呼ばれる ID 番号だけを保管すれば、これによってリクエストをサーバサイドの session オブジェクトと比較できます。URL 書き換えや Hidden フォームフィールドを使用するときは、セッション ID は Cookie の値としてでなく、追加パス情報やフォームフィールドとして渡されます。
ユーザーがアプリケーション内で別のページに移動しても、session オブジェクトに保管された変数は破棄されず、ユーザーセッションが継続している間は保持されます。クライアントがリクエストでセッション ID を送り続けているかぎり、JRun はそのクライアントのユーザー特有のセッションデータにアクセスできます。
まだセッションを開始していないユーザーからアプリケーションのページがリクエストされた場合、JRun は session オブジェクトを作成します。セッションが期限切れになった場合や放棄された場合は、Web サーバによって session オブジェクトが廃棄されます。
session オブジェクトは、セッション ID をクライアントから、設定に従っていくつかの方法で取り出します。サーブレット API はクライアントのセッション ID を取得するサーバの正確な詳細を抽出します。しかし、各メソッドで異なるコーディングテクニックが必要となるために、メソッド間の違いを理解する必要があります。
次の表で、session オブジェクトを実装できるさまざまな方法を説明します。
パーシスタンス メカニズム |
説明 |
---|---|
Cookie |
デフォルトのステート管理メカニズム。Cookie がセッション ID を 保管し、サーバコンポーネントがセッション依存性メソッドを呼び出したときに、サーバがこの ID を取り出します。この Cookie へのリファレンスは、すべてのリクエストでサーバに渡され、すべてのレスポンスで HTTP ヘッダーとしてクライアントに返されます。 これは、特別なコーディングをする必要がないため、最も簡単に実装できる方法です。しかし Cookie を受け付けないブラウザもあります。 Cookie はデフォルトのセッションメカニズムです。 |
Hidden フォームフィールド |
JRun は、ユーザーに隠されたフォームフィールドとしてセッション ID をすべてのリクエストに付加します。このメソッドを使用するには、すべてのページが POST リクエストを処理する必要があります。 セッションメカニズムとしての Hidden フォームフィールドの使用方法の詳細については、 「Hidden フォームフィールドの使用」 を参照してください。 |
URL 書き換え |
JRun は、追加なパス情報としてセッション ID をすべての URL に 付加します。セッション ID を付加するには、すべての URL をエンコードする必要があります。 セッションメカニズムとして URL 書き換えを使用する方法の詳細については、 「URL 書き換えの使用」 を参照してください。 |
アプリケーションは、単純な実装ではユーザー名を記憶し、セキュアな実装ではユーザー名とパスワードを記憶し、電子商取引システムではショッピングカートを維持します。サーブレット API を使用しないアプリケーションの場合、通常はアプリケーション特有のストレージメカニズムを使用してセッション情報を保管し、Hidden フォームフィールド、URL クエリ文字列、または Cookie を使用してキーの値をブラウザに返します。後続のリクエストでは、このキーの値を使用して前に保管されているセッション情報を取得します。
session オブジェクトは、ユーザーが Web サイトに接続している間情報を保管したり取り出したりする、唯一の場所を提供します。
次の方法で、サーブレットと JSP のセッション情報にアクセスできます。
javax.servlet.http.HttpSession
オブジェクトを使用します。
Java サーブレット仕様では HttpSession
インターフェイスが定義されています。このインターフェイスによって、実装の詳細を把握しなくてもセッション管理を行うことができます。HttpSession
インターフェイスは HttpServletRequest
クラスから利用できます。
セッションを使用するファイルを転送またはインクルードするときは、そのセッションを作成した元のリクエストによって、対応する response オブジェクトに Cookie が設定され、このオブジェクトが include
メソッドや forward
メソッドで使用されます。
getSession
メソッドを使用してセッションを確立し、getAttribute
メソッドを使用してセッションの値にアクセスします。
public class SelectionForm extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); String thisName = "Unknown Name"; // ログインフォームからユーザー名を取得します。 String[] attrArray = req.getParameterValues("myName"); // 呼び出し側フォームには、myName の値が 1 つしかないと想定します。 if(attrArray != null && attrArray.length > 0) { thisName = attrArray[0]; } } ...
getSession
メソッドを呼び出すことで新規セッションを作成します。// セッションを作成します。 HttpSession thisSession = req.getSession(true);
setAttribute
メソッドを使用して、属性をセッションに関連付けます。// この例では、ユーザー名を保存します。 thisSession.setAttribute("name", thisName);
HttpServletRequest
オブジェクトの getSession
メソッドを呼び出すことで session
オブジェクトへのリファレンスを取得します。... public class DisplayInfo extends HttpServlet {public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<html><head><title>情報の表示</title></head><body>"); out.println("<h1>displayInfo Servlet</h1>"); // session オブジェクトからログインユーザーを取得します。 HttpSession thisSession = req.getSession(true); ...
HttpSession
オブジェクトの getAttribute
メソッドを使用して属性値にアクセスします。結果は必ず適切なタイプにキャストされます。String userName = (String)thisSession.getAttribute("name");
if(userName != null) { out.println("<h2>ようこそ " + userName + " さん</h2>"); }
パーシスタンス設定と Cookie の設定は jrun-web.xml ファイルで行います。セッションタイムアウト間隔も、Web アプリケーションの web.xml デプロイメントディスクリプタで変更できます。
このセクションでは、jrun-web.xml ファイルと web.xml ファイルを編集することで、設定を変更する方法を説明します。MBean View ユーティリティを使用しても、ランタイムのセッション管理設定を変更できます。jrun.servlet.session.SessionService
サービスではセッションパーシスタンスが定義されます。MBean View の使用方法の詳細については、『JRun 管理者ガイド』を参照してください。JRun には、セッションメカニズムのファイルと JDBC ストレージ実装が含まれています。
session オブジェクトは少量のリソースを使用します。セッションがアクティブな間は、JRun は session オブジェクトを放置します。しかし、アクティブでない期間の後では、JRun は session オブジェクトを廃棄して、未使用のリソースを解放します。
web.xml ファイルでは、session-config
という、1 つのセッション関連の要素が定義されています。この要素には、session-timeout
という 1 つのサブ要素があります。session-timeout
要素では、JRun によってデータストアに保管されたり、廃棄される (パーシスタンスが無効な場合) 前に、session オブジェクトがアクティブでない状態で何分間いられるかが決まります。
デフォルトのセッションタイムアウトは 30 分です。最大値は 34560 分 (24 日) です。session-time-out に 0 や負の値を設定すると、JRun はタイムアウトを行わず、アクティブでない期間がどれだけ続いてもセッションを継続させます。しかし、非常に多くのセッションが作成され、そしてそれが廃棄されなかった場合、JRun は結局セッションをディスクに保存するなどのパーシスタンス方法で、そのステートを維持します。こうすることで、パフォーマンスが低下しリソースが枯渇することがあります。
次の例では、web.xml ファイルでセッションのタイムアウトを 42 分に設定します。
<web-app>
... <session-config> <session-timeout>42</session-timeout> </session-config> ... </web-app>
Cookie を使用するときも、生存期間の最大値を設定できます。この値によって、その Cookie の有効期間がブラウザに指示されます。cookie-max-age
の値と session-timeout
の値は異なる設定を定義します。前に説明したように、セッションがそのセッションのタイムアウトに達すると、JRun はサーバサイドの session オブジェクトを廃棄します。ブラウザサイドでは、cookie-max-age
の有効期限が切れると、ブラウザはその Cookie ファイルを廃棄します。詳細については、 「jrun-web.xml ファイルでのセッション設定」 を参照してください。
Web アプリケーションの jrun-web.xml ファイルを使用すると、各 Web アプリケーションのレベルで、ほとんどの設定が可能です。このセクションで説明した設定を jrun-web.xml ファイルに追加しなかった場合、JRun はデフォルト値を使用します。
セッション設定は、jrun-web-app
ルート要素の下にある session-config
サブ要素で定義されます。session-config
の下で、次のサブ要素を設定できます。
次のセクションで、これらの各要素について説明します。jrun-web.xml ファイルでのセッション設定のサンプル設定については、 「セッション設定の例」 を参照してください。
次の表で、persistence-config
要素で利用可能な要素を説明します。
次の表で、cookie-config
要素で設定できる要素を説明します。
要素 |
説明 |
デフォルト |
---|---|---|
active |
Cookie が有効かどうかを指定します。 |
true |
cookie-max-age |
秒単位で Cookie の最大生存期間を設定します。この値はブラウザサイドの Cookie に保管されます。その Cookie の有効期間がブラウザに指示されます。 正の値を指定した場合、指定した時間サーバとの対話がないと、ブラウザは Cookie ファイルを削除します。 負の値や 0 を指定した場合、現在のセッションが完了すると、ブラウザは Cookie を保管しません。 cookie-max-age の値と session-timeout の値は異なる設定を定義します。 「セッションタイムアウトの変更」 で説明されているように、セッションがそのセッションタイムアウトに達すると、JRun はサーバサイドの session オブジェクトを廃棄します。ブラウザサイドでは、 cookie-max-age の有効期限が切れると、ブラウザはその Cookie ファイルを廃棄します。 |
-1 |
cookie-secure |
HTTPS や SSL などのセキュアプロトコルだけを使用して、Cookie が送信されるかどうかをブラウザに示します。 |
false |
cookie-domain |
Cookie が送信されるドメインを設定します。 ドメイン名はドットで始まるため (.foo.com など)、特定の DNS (Domain Name System) 領域にあるサーバでは Cookie を見ることができます (たとえば、www.foo.com。a.b.foo.com は違います)。ドメイン名の形式は、RFC2109 で指定されています。 デフォルトでは、Cookie はその送信元サーバだけに返されます。 |
該当なし |
cookie-comment |
Cookie の目的を説明するコメントを指定します。Web ブラウザがユーザーに Cookie を表示する 場合、このコメントは役に立ちます。このコメントは Netscape の Cookie バージョン 0 ではサポートされていません。 |
該当なし |
cookie-path |
クライアントが Cookie を返すパスを設定します。 この Cookie は、指定するディレクトリ内のすべてのページや、そのディレクトリのサブディレクトリ内のすべてのページから可視です。Cookie のパスには、その Cookie を設定したサーブレットを含める必要があります。たとえば /catalog を指定すると、その Cookie は /catalog の下にあるそのサーバ上のすべてのディレクトリから可視になります。 |
/ |
cookie-name |
セッションの Cookie 名を設定します。この名前に使用できるのは、コンマ、セミコロン、空白文字を除く ASCII 英数文字のみであり、$ 文字を先頭にすることはできません。 この名前は RFC2109 に準拠する必要があります。 |
JSESSIONID |
次の表で、replication-config
要素で設定できる要素を説明します。
要素 |
説明 |
デフォルト |
---|---|---|
active |
セッションレプリケーションが有効かどうかを示します。 |
false |
buddy-name |
クラスタ内でローカルセッションを複製する特定のサーバを指定します。* に設定すると、クラスタ内のすべてのサーバに継続セッションを複製します。これは大規模クラスタではお勧めできません。 |
該当なし |
次の例は、jrun-web.xml ファイルでのパーシスタンス設定を示しています。
<jrun-web-app>
... <session-config> <persistence-config> <active>true</active> <persistence-type>file</persistence-type> <persistence-synchronized>true</persistence-synchronized> <class-change-option>reload</class-change-option> <session-swapping>true</session-swapping> <session-swap-interval>5</session-swap-interval> <session-max-resident>500</session-max-resident> <init-param> <param-name>foo</param-name> <param-value>bar</param-value> </init-param> </persistence-config> <cookie-config> <active>true</active> <cookie-max-age>-1</cookie-max-age> <cookie-secure>true</cookie-secure> <cookie-domain>foo</cookie-domain> <cookie-comment>george</cookie-comment> <cookie-path>bar</cookie-path> <cookie-name>jsessionid</cookie-name> </cookie-config> </session-config> ... </jrun-web-app>
Cookie は無効にできますが、その場合でも JRun で URL 書き換えや Hidden フォームフィールドなどの他のセッションパーシスタンス手段を使用できます。JRun で Cookie を無効にするには、次の例に示すように、cookie-config
の active
要素の値を false に変更します。
...
<session-config> <cookie-config> <active>false</active> </cookie-config> </session-config> ...
Cookie を無効にし、ユーザーに提供する URL で request オブジェクトの encodeURL
メソッドを呼び出すことによって、URL 書き換えをセッションメカニズムとして使用できます。 JRun がエンコードされた URL を構築すると、JRun は、JSESSIONID
いう名前のクエリ文字列パラメータとしてセッション ID をそのエンコードされた URL に付加します。そして、その URL クエリ文字列からセッション ID を取得することによって、JRun はそのユーザーに関連付けられた session オブジェクトにアクセスできます。
URL 書き換えは明示的には有効にしません。クライアントのブラウザで Cookie が無効の場合や、管理者が Cookie を無効にした場合、JRun は、JRun の設定を管理者に確認せずに URL 書き換えを使用します。
しかし、セッションメカニズムとして URL 書き換えを使用するには、JRun に対して次の作業を行う必要があります。
encodeURL
メソッドを使用して、ユーザーに送信される URL をエンコードします。メモ: クライアントがブラウザで Cookie を無効にしていないか、または JRun で Cookie を無効にしていないかぎり、たとえ URL で encodeURL
メソッドを使用している場合でも、JRun はセッション ID をこれらの URL に追加しません。
サーブレットや JSP で URL 書き換えを実行するには、session オブジェクトを使用するページで、request オブジェクトの encodeURL
メソッドを使用して、クライアントに返す各 URL をエンコードする必要があります。次の例では URL をエンコードします。
String originalURL = "/servlet/URLRewriter";
String encodedURL = response.encodeURL(originalURL); out.println("<P><a href=¥"" + encodedURL + "¥">This link contains a JSESSIONID</a> (if cookies are disabled)");
URL をエンコードし、出力をクライアントに送信する前に session オブジェクトのインスタンスを作成する必要があります。
サンプルサーブレットを表示するには、samples JRun サーバを起動し、ブラウザで http://localhost:8200/techniques を開きます。
ローカルマシンで URL 書き換えをテストするには、いくつかの手順を行う必要があります。
JSESSSIONID=xxxxxxxxxxxxxxxxx
が付加されます。ここで、連続した x はセッション ID を表します。
セミコロンに続く URI のパス情報の最後にセッション ID を付加すると、URL 書き換えを明示的に強制できます。これは多くの場合 URL の最後に現れますが、JSESSIONID
はクエリ文字列パラメータではなく、パス情報の一部です。
次の例では、明示的に JSESSIONID
パラメータを設定します。
...
HttpSession thisSession = request.getSession(true); String originalURL = "/servlet/Logger"; String newURL = originalURL + ";JSESSIONID=" + thisSession.getId() + request.getQueryString(); ...
FORM
タグで送信した隠しフィールドを使用して、クライアントからサーバにセッション ID を渡すことができます。
セッションメカニズムとして Hidden フォームフィールドを使用することには、次の欠点があります。
FORM
タグが必要です。
FORM
を送信する必要があります。
Hidden フォームフィールドを使用するには、セッションを作成した後そのセッションの ID を FORM
要素の session
フィールドの値として使用します。次の例は、FORM
が送信されたときに、クライアントからサーバにセッション ID を渡すサーブレットの FORM
を示しています。
...
HttpSession session = request.getSession(true); out.println("<FORM METHOD=¥"POST¥" ACTION=¥"HiddenForm¥">"); out.println("<INPUT TYPE=¥"HIDDEN¥" NAME=¥"session¥" VALUE=¥"" + session.getId() + "¥">"); out.println("<INPUT TYPE=¥"Submit¥" VALUE=¥"Submit¥"></FORM>"); ...
サンプルサーブレットを表示するには、samples JRun サーバを起動し、ブラウザで http://localhost:8200/techniques を開きます。