一、Servletとは
Servletは、Javaで記述されたサーバーサイドのプログラムです。特定のプラットフォームやプロトコルに依存せず、主にHTTPリクエストを受け取って動的なWebコンテンツを生成するための仕組みです。HTTPサーバーの機能を拡張する形で利用されることが最も多く、フォームデータの取得やセッション管理、動的なHTMLの生成などに活用されます。
二、Servletの動作原理と処理の流れ
1. 動作原理
Servletコンテナ(Tomcatなど)がServletクラスをメモリに読み込み、Servletインスタンスを生成して適切なメソッドを呼び出します。ただし、アプリケーション内では1種類のServletクラスに対して1つのインスタンスしか作られません。
クライアントからのリクエストが発生すると、ServletコンテナはServletRequestオブジェクトとServletResponseオブジェクトを生成し、Servletのservice()メソッドに渡します。これらのオブジェクトはコンテナが用意するため、開発者が自分で実装する必要はありません。
- ServletRequest:現在のHTTPリクエスト情報を保持しています。
- ServletResponse:クライアントへのHTTPレスポンスを表します。
- ServletContext:アプリケーション全体の環境情報を保持します。アプリケーションごとに1つだけ存在します。
- ServletConfig:Servlet個別の初期化設定を保持します。Servletごとに1つ存在します。
2. 処理の流れ
- クライアントがサーバーにリクエストを送信する。
- サーバーがServletを呼び出し、Servletはリクエストに応じたレスポンス内容を生成してサーーに返す。
- サーバーがそのレスポンスをクライアントに返信する。
三、Servletインターフェース
public interface Servlet {
void init(ServletConfig config) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
1. ライフサイクルメソッド
- init():Servletの初期化を行います。Servletが初めてリクエストを受けた際に、Servletコンテナによって1回だけ呼ばれます。以降のリクエストでは再度呼ばれません。
- service():Servletに対するリクエストが発生するたびに呼ばれます。初回リクエスト時は
init()実行後に呼ばれ、2回目以降はinit()を省略して直接呼ばれます。 - destroy():アプリケーションがアンデプロイされるか、Servletコンテナが停止されるときに呼ばれ、Servletのリソースを解放します。
2. その他のメソッド
- getServletConfig():
init()に渡されたServletConfigオブジェクトを返します。 - getServletInfo():Servletの概要を表す文字列を返します。
3. ライフサイクル
Servletのライフサイクルは、init() → service() → destroy() の順で進行します。これは、Servletが「生成され」「処理を実行し」「破棄される」までの一連の流れを表します。
四、設定例と実装
以下は、web.xmlによるServletの定義と、対応するServletクラスの実装例です。
web.xml
<!-- Servletの登録 -->
<servlet>
<servlet-name>greetingServlet</servlet-name>
<servlet-class>com.example.web.GreetingServlet</servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Hello, Servlet!</param-value>
</init-param>
<!-- 起動時の優先度。0以上は起動時に初期化。数値が小さいほど優先度が高い。 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>greetingServlet</servlet-name>
<url-pattern>/greet</url-pattern>
</servlet-mapping>
GreetingServlet.java
package com.example.web;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
public class GreetingServlet implements Servlet {
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("GreetingServlet initialized.");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>" + LocalDateTime.now() + "</h1>");
out.println("<p>Servletによる動的な応答です。</p>");
out.println("</body></html>");
}
@Override
public String getServletInfo() {
return "Greeting Servlet Sample";
}
@Override
public void destroy() {
System.out.println("GreetingServlet destroyed.");
}
}
この例では、/greetへのアクセスが発生すると、GreetingServletのservice()メソッドが実行され、現在時刻を含むHTMLがクライアントに返されます。