Powered by SmartDoc

セッション管理

セッション

HTTPでは、WebブラウザとWebサーバが次のようにして通信します。

  1. WebブラウザとWebサーバが接続される
  2. Webブラウザが要求を出す
  3. Webサーバが応答を返す
  4. 接続を切断する

この一連の流れを「セッション」と言います。あるセッションと別のセッションとは、基本的には無関係です。

ところが、これでは困る場合があります。例えば、インターネット上のショッピングサイトで、「商品Aを購入」というボタンをクリックしたとします。これをセッションAとしましょう。続けて、「商品Bを購入」というボタンをクリックしたとします。これをセッションBとしましょう。このユーザは商品Aと商品Bを購入したいわけですね。しかし、Webサーバにとっては、セッションAとセッションBは無関係です。つまり、「商品Aを購入」ボタンを押したユーザと「商品Bを購入」ボタンを押したユーザとは無関係ということになります。これでは困りますね。

そこで、これらのセッションをひとまとめにする仕組みが必要になります。これが「セッション管理」です。

セッション管理の基本

セッションID

セッション管理では、要求のあったユーザ(Webブラウザ)を識別することが必要になります。

Webサーバは、セッション管理が必要になった時点で、Webブラウザに「セッションID」という番号を渡します。Webブラウザは、その後で同じWebサーバにアクセスするときに、このセッションIDをWebサーバに渡します。

このセッションIDによって、ユーザ(Webブラウザ)を識別します。

セッションIDの渡し方にはいくつか方法があります。ここでは、「Cookie」と「URL Rewriting」について簡単に解説します。

Cookie

Cookieは、セッション管理でいちばんよく用いられている手法です。Webブラウザ側のコンピュータにテキストファイルとして保存できます。また、Webブラウザを終了したときに、自動的にCookieを削除することもできます。

Cookieには、セッションIDのほか、関連する情報を含めることができます。例えば、ショッピングサイトで選択された商品の情報をすべて含めることもできます。しかし、セッション管理に必要な情報がすべてクライアントに渡されてしまうので、パフォーマンスが低下することもあります。

Cookieを使えない場合もあります。Webブラウザ側でCookieの受入を拒否することができます。そうするとCookieは使えません。また、多くの携帯電話ではCookieは使えません。

URL Rewriting

Cookieが使えない環境の場合、代わりに使われる手法です。セッションIDをURLに埋め込んで渡します。

例えば、Webサーバが生成するWebページに、次のようなリンクを含めます。このidというパラメータがセッションIDです。

  <a href=http://hogehoge.com/test/select?id=12345>購入</a>

Webブラウザ側でこのURLをクリックすると

  http://hogehoge.com/test/select?id=12345

がWebサーバへの要求となります。これでセッション管理が可能になります。

しかし、この方法ではセッションIDがURL中に露出します。そのため、セキュリティの面から見ると好ましくない方法です。

HttpSession

HttpSession の使い方

Javaでは、セッション管理を手軽に行うために、javax.servlet.http.HttpSessionというインタフェースが用意されています。

HttpSessionは、HttpServletRequestから取得できます。HttpSessionが無い場合は、新しく生成されます。このとき、セッションIDも生成されます。

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
                      throws ServletException, IOException {
        .....
        .....
        HttpSession session = request.getSession();
        .....
        .....
    }

HttpSessionにはオブジェクトを登録できます。次の例では、bookListという名前で、listというオブジェクトをHttpSessionに登録しています。

        session.setAttribute("bookList", list);

HttpSessionから、bookListという名前で登録されているオブジェクトを取り出しています。

        BookList list = session.getAttribute("bookList");

bookListという名前で登録されているオブジェクトを削除します。

        session.removeAttribute("bookList");

HttpSessionを終了させます。セッションが終了します。

        session.invalidate();

セッションIDの受け渡し

HttpSessionでは、CookieとURLRewritingのいずれかを、Webクライアントの状況に応じて自動的に使い分けます。基本的にはCookieを利用します。このCookieは、セッションIDだけがセットされたものです。その他の情報は、すべてWebサーバ側に置かれます。

Cookieを使えない場合は、URL Rewritingが利用されます。先に説明したように、URL RewritingではWebサーバへの要求のときに、URLにセッションIDを含める必要があります。ここで便利なのがHttpServletResponseのencodeURLメソッドです。

  response.encodeURL("http://hogehoge.com/test/select");

のようにすることで、URL Rewritingが利用される場合には、

  http://hogehoge.com/test/select?id=12345

のように、自動的にURLにセッションIDを追加します。Cookieが利用される場合には、何も追加しません。

ですから、セッション管理が必要になるようなリンクをクリックさせる場合には、このencodeURLメソッドを利用すると良いでしょう。

セッションタイムアウトの処理

セッションには有効期間があります。

Tomcatのデフォルトの設定では、30分間HttpSessionへのアクセスがないと、そのセッションは破棄されます。

ひとつのHttpSessionを複数のServletやJSPで使いまわす場合、request.getSessionメソッドでHttpSessionオブジェクトを新規に生成するのは最初の1回だけにしておき、他のプログラムでは新規作成はしない方が良いでしょう。getSessionメソッドの引数をfalseにすることで、HttpSessionが無い場合だと新しいオブジェクトが生成されず、nullを返すようになります。

そうした方がよい理由は、セッションの途中でタイムアウトが起きた場合、予想外のところでHttpSessionオブジェクトが生成されると、さまざまな矛盾の発生が考えられるからです。

        HttpSession session = request.getSession(false);