Javaサーブレットの基本

## サーブレットとは

サーブレットとは、JavaでWebアプリケーションを作成するための技術標準の1つです。サーブレットは、Webサーバー上で実行されるJavaプログラムで、クライアントからのリクエストを受け取り、必要な処理を行った後、レスポンスを返します。

サーブレットの主な特徴は以下の通りです。

- プラットフォームに依存しない
- マルチスレッド対応
- 軽量
- 拡張性が高い

## サーブレットのライフサイクル

サーブレットには、以下のようなライフサイクルがあります。

1. **インスタンス化** - サーブレットのインスタンスが生成される。
2. **初期化** - `init()`メソッドが呼び出される。
3. **サービス** - `service()`メソッドが呼び出され、HTTP リクエストに応じた処理が行われる。
4. **破棄** - `destroy()`メソッドが呼び出され、サーブレットインスタンスが破棄される。

```mermaid
graph LR
A[インスタンス化] --> B[初期化]
B --> C[サービス]
C --> D[破棄]
```

## サーブレットの作成手順

サーブレットを作成する手順は以下の通りです。

1. `HttpServlet`クラスを継承したサーブレットクラスを作成する。
2. `doGet()`、`doPost()`などのメソッドをオーバーライドし、HTTP リクエストに応じた処理を記述する。
3. `web.xml`ファイル、またはアノテーションを使って、サーブレットをWebアプリケーションに登録する。

### サンプルコード

以下は、簡単なサーブレットの例です。

```java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {

   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       response.setContentType("text/html");
       response.getWriter().println("<h1>Hello, Servlet!</h1>");
   }
}
```
このサーブレットは、GETリクエストに対して Hello, Servlet! と応答します。

## サーブレットの高度な使い方

### HTTPリクエストの処理

サーブレットでは、`HttpServletRequest`オブジェクトを使用してHTTPリクエストの情報(リクエストパラメータ、ヘッダー、Cookie等)にアクセスできます。

```java
String name = request.getParameter("name"); // リクエストパラメータの取得
String headerValue = request.getHeader("User-Agent"); // ヘッダーの取得
```

### HTTPレスポンスの処理

`HttpServletResponse`オブジェクトを使用して、HTTPレスポンスを構築できます。

```java
response.setStatus(HttpServletResponse.SC_OK); // ステータスコードの設定
response.setContentType("text/html"); // コンテンツタイプの設定
response.addHeader("Cache-Control", "no-cache"); // ヘッダーの設定
```

### JSPとの連携

サーブレットとJSP(JavaServer Pages)を組み合わせることで、プレゼンテーション層とロジック層を分離したWebアプリケーションを作成できます。

```java
// フォワード
request.getRequestDispatcher("/WEB-INF/view/result.jsp").forward(request, response);

// インクルード
request.getRequestDispatcher("/WEB-INF/templates/header.jsp").include(request, response);
```

### フィルタの利用

フィルタを使用すると、リクエストやレスポンスを横断的に処理できます。認証、ロギング、圧縮などの用途に活用できます。

```java
// フィルタの例
public class LoggingFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        long start = System.currentTimeMillis();
        chain.doFilter(request, response); // 次のフィルタ、またはサーブレットの呼び出し
        long elapsed = System.currentTimeMillis() - start;
        log.info("Request processed in " + elapsed + "ms");
    }
}
```

### 非同期処理

サーブレット3.0以降では、非同期処理がサポートされています。長時間実行するタスクを別スレッドで実行し、メインスレッドをブロックしないようにできます。

```java
public class AsyncServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.start(new Runnable() {
            public void run() {
                // 長時間実行するタスクをここで実行
                asyncContext.complete(); // 処理が完了したらここを呼ぶ
            }
        });
    }
}
```