Java Servlet リスナー

『日暮らし  上・中・下(著:宮部みゆき)』読了しました。前作の『ぼんくら』を読んだのがだいぶ前になるので、前の登場人物の記憶がおぼろげですが、そんなに気にならず読めます。葵さんの扱いがちょっとひどいような気もしますが。

そんなこんなで、JavaJSPServletでリスナーとフィルターというものを習いましたが、今回はリスナーについてです。

リスナーとは

リスナーというクラスを用意しておくと、Webアプリケーションの状況に応じて処理を行ってくれるようです。そのためには、Javaが用意してくれているリスナーインターフェイスというものを実装したクラスを用意する必要があります。 

リスナーインターフェイスサーブレットのバージョン3.0を目安)

リスナーインターフェイス 対応イベント
ServletContextListener Webアプリケーションの開始または終了
ServletContextAttributeListener アプリケーションスコープへのインスタンスの保存、上書き保存、削除
HttpSessionListner セッションスコープの作成または破棄
HttpSessionAttributeListener セッションスコープへのインスタンスの保存、上書き保存、削除
HttpSessionActivationListener セッションスコープの退避または回復
HttpSessionBindingListener このインターフェイスを実装したクラスのインスタンスをセッションスコープに保存、または削除
ServletRequestListener リクエストの発生、またはレスポンスの完了
ServletRequestAttibuteListener リクエストスコープへのインスタンスの保存、上書き保存、削除

サーブレットのバージョンによって使用できるリスナーインターフェイスが異なるようです。 

 

リスナーを使ってみる

新しく、「動的 Web プロジェクト」を作成します。Eclipseを起動し、

f:id:ts0818:20170808232334j:plain

パースペクティブ」が「Java EE」になっていることを確認し、

f:id:ts0818:20170808232333j:plain

「ファイル」>「新規(N)」>「動的 Web プロジェクト」をクリック。

f:id:ts0818:20170808202204j:plain

「プロジェクト名(M):」を入力し、「次へ(N)>」をクリック。

f:id:ts0818:20170808202201j:plain

「次へ(N)>」をクリック。

f:id:ts0818:20170808202156j:plain

「完了(F)」をクリック。

f:id:ts0818:20170808202153j:plain

続いて、「リスナー」の作成。

「src」を選択した状態で、右クリックし「新規(N)」>「リスナー」をクリック。

f:id:ts0818:20170808202149j:plain

Java パッケージ(K):」、「クラス名(M):」を入力し、「次へ(N)>」をクリック。

f:id:ts0818:20170808202903j:plain

今回は、「サーブレット・コンテキスト・イベント」の「ライフサイクル(L)」にチェックし、「次へ(N)>」をクリック。

f:id:ts0818:20170808202900j:plain

インターフェイス(I):」に「javax.servlet.ServletContextListner」が追加されてるのを確認し、「完了(F)」をクリック。

f:id:ts0818:20170808202856j:plain

続いて、サーブレットの作成。

「src」を選択した状態で、右クリックし「新規(N)」>「サーブレット」をクリック。

f:id:ts0818:20170808202853j:plain

Java パッケージ(K):」、「クラス名(M):」を入力し、「次へ(N)>」をクリック。

f:id:ts0818:20170808202848j:plain

「次へ(N)>」をクリック。

f:id:ts0818:20170808203523j:plain

 「継承された抽象メソッド(H)」、「init」、「destroy」、「doGet(G)」 にチェックをし、「完了(F)」をクリック。

f:id:ts0818:20170808203851j:plain

リスナーとサーブレットが作成されました。 

f:id:ts0818:20170808204224j:plain

ファイルを編集。

CounterServlet.java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class CounterServlet
 */
@WebServlet("/CounterServlet")
public class CounterServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  /**
   * @see Servlet#init(ServletConfig)
   */
  public void init(ServletConfig config) throws ServletException {

    super.init(config);

    // 訪問回数を表すInetgerインスタンスを作成
    // アプリケーションスコープに保存
    Integer count = 0;
    ServletContext application = config.getServletContext();
    application.setAttribute("count", count);
  }

  /**
   * @see Servlet#destroy()
   */
  public void destroy() {
    //
    System.out.println("destroy()の実行");
  }

  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // アプリケーションスコープに保存された訪問回数を更新
    ServletContext application = this.getServletContext();
    Integer count = (Integer)application.getAttribute("count");
    count++;
    application.setAttribute("count", count);

    // HTMLの出力
    response.setContentType("text/html; charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("");
    out.println("");
    out.println("リスナー");
    out.println("");
    out.println("");
    out.println("

訪問回数: " + count + "

");
    out.println("更新");
    out.println("");
    out.println("");
  }

}

ListenerSample.java

package listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/**
 * Application Lifecycle Listener implementation class ListenerSample
 *
 */
  @WebListener
  public class ListenerSample implements ServletContextListener {

    /**
     * Default constructor.
     */
    public ListenerSample() {

    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent sce)  {

    }

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce)  {
      //
      ServletContext context = sce.getServletContext();
      Integer count = 0;
      context.setAttribute("count", count);
    }

}

実行します。「CounterServlet.java」を選択した状態で、右クリックし「実行(R)」「サーバーで実行」をクリック。

f:id:ts0818:20170808221737j:plain

「次へ(N)>」をクリック。

f:id:ts0818:20170808220332j:plain

「構成済み(C):」にプロジェクトが追加されているのを確認し、「完了(F)」をクリック。

f:id:ts0818:20170808220327j:plain

「コンソール」を確認すると、サーブレットのinit()メソッドより先にリスナー contextInitialize()メソッドが 実行されています。

f:id:ts0818:20170808221651j:plain

「サーバー」を停止してみます。

f:id:ts0818:20170808221648j:plain

「コンソール」で「」すると、リスナーのcontextDestroyed()メソッドが一番最後に実行されています。

f:id:ts0818:20170808221643j:plain

リスナーインターフェイスにServletContextListenerを指定することで、Webアプリケーションの一番最初に実行したい処理は、contextInitialize()メソッドに、最後に実行したい処理は、contextDestroyed()メソッドに記述すれば良さそうです。

 

⇩  web.xmlを使う場合のリスナーの使い方は下記サイトへ 

Javaの道:Servlet(8.リスナー(ServletContext))

 

まだ、使いどころが思いつかないですが、リスナーという存在を新しく知ることができました。