サーブレットの基礎知識

複数のリクエストにはセッションオブジェクトを活用する

テンアートニ 中越智哉
2001/6/6

 サーブレットは、基本的にマルチスレッドで動作します。リクエストが同時に複数あった場合は、それぞれのリクエストが別のスレッドで動作します。

 しかし、その際のインスタンス変数の扱いについては意外と誤解している方が多いようです。

 インスタンス変数は、サーブレットであってもスレッド間で値が共用されます。例えば次のようなサーブレットを考えましょう。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public class CounterServlet1 extends HttpServlet {

   private int count; // カウンタの値(インスタンス変数)

  public void init() {
    count=0;
  }

  public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {

    response.setContentType("text/html; charset=Shift_JIS");
    PrintWriter out = response.getWriter();out.println("<HTML>");

    out.println("<HEAD><TITLE>CounterServlet1</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<H1>Count:["+count+"]</H1>");
    out.println("</BODY>");
    out.println("</HTML>");
    out.close();

    count++; // カウンタの値を増やす

    }
}

 このサーブレットでは、カウンタをインスタンス変数として定義し、リクエストごとに値を増やして表示するという処理を行っています。もし、スレッドごとにインスタンス変数も別に保持しているならば、別々のブラウザからアクセスしても、カウンタの値は共通にならないはずです。ですが、実行してみると、カウンタの値は1種類しか保持されていません。このように、インスタンス変数には、クライアントごとに固有の値を保持することはできないのです。もし、そういったクライアントごとに固有の値を保持したい場合には、セッションオブジェクトを利用する必要があります。

 上記のサーブレットを、セッションオブジェクトを用いて実装したのが、次のサーブレットです。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public class CounterServlet2 extends HttpServlet {


  public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {


  // カウンタの値
  int count;


  // セッションが開始していなければ、新規のセッションを開始する
  // すでに開始していれば、継続して値を増加する。
  HttpSession session = request.getSession(false);
  if ( session == null ) {
    // 新規セッションの開始
    session = request.getSession(true);
    // カウンタに初期値を代入
    count = 0;
  } else {
    // セッションが継続されていた場合、
    // Session Objectから値を取り出す
    Integer n = (Integer)session.getAttribute("Count");
    count = n.intValue();
  }


  // HTML表示
  response.setContentType("text/html; charset=Shift_JIS");
  PrintWriter out = response.getWriter();

  out.println("<HTML>");
  out.println("<HEAD><TITLE>CounterServlet2</TITLE></HEAD>");
  out.println("<BODY>");
  out.println("<H1>Count:["+count+"]</H1>");
  out.println("</BODY>");
  out.println("</HTML>");
  out.close();


  // カウンタの値を増やして、セッションに格納
  count++;
  session.setAttribute("Count",new Integer(count));


  }

}

 こうすれば、別のクライアントからのアクセスごとに、固有の値を保持することができます。別々の2種類のWebブラウザ(IEとNetscapeなど)から、それぞれアクセスすると、個別にカウンタの値を保持していることが確認できます。

「Java Solution FAQ」




Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間