Web系開発メモ

Java, C#, HTML, CSS, JavaScript のことなどを書いてます。

ServletRequestListener リクエストの処理前後に通知を受ける

ServletRequestListener を使って、以下のタイミングで処理を行う方法を書いていきます。

バージョン

サーブレットのバージョンは以下の通りです。

動作確認用プロダクト

動作確認のために、以下の製品を使用しました。

目次

  1. リスナーの作成
  2. サーブレットの作成
  3. フィルターの作成
  4. ディレクトリ階層の作成
  5. pom.xml の作成
  6. 動作確認

1. リスナーの作成

ServletRequestListener を実装するクラスを作成します。

org/example/listener/RequestListener.java

package org.example.listener;

import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
import jakarta.servlet.annotation.WebListener;

@WebListener
public class RequestListener implements ServletRequestListener {
  // リクエストの処理開始時に呼び出されるメソッド
  @Override
  public void requestInitialized(ServletRequestEvent sre) {
    System.out.println("リスナー:処理開始");
  }

  // リクエストの処理終了時に呼び出されるメソッド
  @Override
  public void requestDestroyed(ServletRequestEvent sre) {
    System.out.println("リスナー:処理終了");
  }
}

アノテーション @WebListener を付けて、サーブレットコンテナに認識されるようにしています。

2. サーブレットの作成

動作確認のために、以下のサーブレットを作成します。

org/example/listener/SampleServlet.java

package org.example;

import java.io.IOException;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/listener/servlet")
@SuppressWarnings("serial")
public class HelloServlet extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException
  {
    System.out.println("サーブレット:処理開始");
  }
}

3. フィルターの作成

動作確認のためにフィルターを作成します。

org/example/listener/SampleFilter.java

package org.example.listener;

import java.io.IOException;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;

@WebFilter("/listener/servlet")
public class SampleFilter implements Filter {
  @Override
  public void doFilter(
    ServletRequest req, ServletResponse res, FilterChain chain)
  throws IOException, ServletException {
    System.out.println("フィルター:前処理");
    chain.doFilter(req, res);
    System.out.println("フィルター:後処理");
  }
}

上のサーブレットが呼び出されるタイミングで処理を追加しています。

4. ディレクトリ階層の作成

以下のコマンドでプロジェクト sample-servletディレクトリ階層を作成します。

mkdir sample-servlet
cd sample-servlet
mkdir src\main\java
mkdir src\main\webapp\WEB-INF

作成したら、src/main/java 配下にコードを置きます。

5. pom.xml の作成

フォルダ sample-servletpom.xml を作成します。

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>sample-servlet</artifactId>
  <version>1.0.0</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>5.0.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.4.0</version>
      </plugin>
      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>11.0.15</version>
        <configuration>
          <scan>1</scan>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

サーブレットコンテナを起動できるように、build で Jetty Plugin を定義しています。

6. 動作確認

以下のコマンドでコンテナを起動します。

sample-servlet> mvn jetty:run

起動後にブラウザで以下の URL を開きます。

http://localhost:8080/listener/servlet

以下の文字列が標準出力されます。

リスナー:処理開始
フィルター:前処理
サーブレット:処理開始
フィルター:後処理
リスナー:処理終了

※ ブラウザが favicon.ico をリクエストするため、リスナーの標準出力が2回になることがあります。