0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java用語、結局なんだっけ? #3】Web/サーバー編 ― サーブレット・JSP・Tomcat・WAR・フィルタ

0
Posted at

はじめに

株式会社Good Labでエンジニアをしている コータロー です。
日々、Java・SQL・Gitなどの技術情報や、新人エンジニア向けの学習ノウハウ、
AI活用についての情報を発信しています。

Good Labについて気になった方は、コーポレートサイトもぜひご覧ください。
コーポレートサイト

「Java用語、結局なんだっけ?」シリーズの第3回です。

テーマ
#1 環境・基盤編
#2 DB接続編
#3(本記事) Web/サーバー編
#4 例外・スレッド編
#5 モダンJava編
#6 フレームワーク編
#7 ビルド・運用編

今回は Web/サーバー編 です。Spring Boot 全盛の今でも、内部で動いているのは「サーブレット」と「Webコンテナ」。現場で必ず出てくる土台用語 を整理します。


この記事のゴール

  • サーブレット・JSP・Tomcatの関係を説明できる
  • WAR ファイルとは何か説明できる
  • フィルタの役割を説明できる
  • ステートフル / ステートレスを使い分けられる

全体像:ブラウザからJavaアプリまで

[ブラウザ]
   ↓ HTTPリクエスト
[Webコンテナ(Tomcat等)]   ← サーバー本体
   ↓ サーブレット仕様に沿って渡す
[フィルタ]                  ← 前処理(認証、ログ等)
   ↓
[サーブレット / JSP]        ← アプリ本体
   ↓ HTTPレスポンス
[ブラウザ]

これらの用語を7つに分けて解説します。


① サーブレット ― 「HTTPリクエストを処理するJavaクラス」

一言で言うと

HTTPリクエストを受け取り、HTTPレスポンスを返すJavaクラス です。
Web版の「main関数」のような役割を果たします。

概念コード(最小サンプル)

// ※ 実際のサーブレットは jakarta.servlet-api 依存が必要
public class UserServlet {
    void service(HttpRequest request, HttpResponse response) {
        if (request.getMethod().equals("GET")) {
            response.setStatus(200);
            response.setBody("User found: " + request.getParam("id"));
        }
    }
}

実際の HttpServlet を継承する書き方:

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String id = req.getParameter("id");
        resp.setStatus(200);
        resp.getWriter().write("User ID: " + id);
    }
}

サーブレットは何が嬉しい?

  • HTTPプロトコルの低レベルな部分(ヘッダ解析、Content-Length、Cookie等)を すべてコンテナ側がやってくれる
  • 開発者は 「リクエストを受けて、レスポンスを返す」 ロジックだけ書けばよい

よくある誤解

  • 「サーブレット = 古い技術、もう使わない」:Spring MVC や Spring Boot の内部は サーブレット仕様の上に乗っている。直接書かないだけで、間接的には現役。
  • 「サーブレットは小さなアプリ」:「Servlet」は「Server-let(サーバーで動く小プログラム)」が由来だが、実体は普通のJavaクラス。

② JSP(JavaServer Pages) ― 「HTMLにJavaを埋め込むテンプレート」

一言で言うと

HTMLの中にJavaコードを書けるテンプレート技術です。
拡張子は .jsp。実行時にサーブレットに変換されます。

コード例

<%@ page contentType="text/html; charset=UTF-8" %>
<%
    String name = (String) request.getAttribute("userName");
%>
<html>
<body>
<h1>こんにちは、<%= name %>さん</h1>
</body>
</html>

<% %> の中はJavaコード、<%= %> は「式の値を出力」という記号。

現代でJSPは使われている?

新規開発では ほとんど使われません。代わりに以下が主流:

用途 現代の選択肢
サーバーサイドテンプレート Thymeleaf、FreeMarker
API(JSONを返す) Spring @RestController + Jackson
SPA(ブラウザ側で描画) React、Vue、Angular

ただし 既存のレガシー案件には大量に存在 するので、SES現場では今でも触ることがあります。

よくある誤解

  • 「JSPはJavaScriptと同じもの」:全くの別物。JSPはサーバーサイド、JavaScriptはブラウザサイド。
  • 「JSP内でビジネスロジックを書く」:アンチパターン。JSPは「表示専用」で、ロジックはサーブレット(または Controller)で書くのが正解。

③ Webコンテナ ― 「サーブレットを動かすサーバー」

一言で言うと

サーブレット仕様に従ってJavaのWebアプリを動かすサーバー です。
代表例は Tomcat

何をしてくれる?

機能 説明
HTTP受信 ポートを開いてリクエストを受信
マッピング URLとサーブレットを紐付け(例:/usersUserServlet
ライフサイクル管理 サーブレットの初期化(init)・破棄(destroy
スレッド管理 1リクエスト=1スレッドで並列処理
JSP変換 .jsp をサーブレットに変換して実行

主なWebコンテナ

名前 概要
Tomcat 業界標準のOSS。Spring Boot にも組み込み版が同梱
Jetty 軽量・高速。組み込み用途で人気
Undertow Red Hat製。Spring Boot WebFlux等で採用
GlassFish / WildFly Java EE / Jakarta EE 対応のフルスタック

Spring Boot は Tomcat を「内蔵」している

新人がよく混乱するのが「Spring Boot は Tomcat なしで動くのか?」という疑問。
答えは 「内蔵Tomcatで動いている」 です。

java -jar myapp.jar       ← jarファイル1つで起動
  ↓ Spring Boot が内部的に Tomcat を起動
  ↓ Tomcat がサーブレットコンテナとして機能
  ↓ Spring の DispatcherServlet がリクエストを受ける

「サーバーにTomcatをインストール → WARをデプロイ」という昔のスタイルは、現代の新規案件ではほぼ無くなりました。

よくある誤解

  • 「Tomcat = サーバーOS」:違う。Tomcatは JavaのプロセスとしてLinux/Windows上で動く
  • 「Spring Boot は Tomcat を置き換えた」:違う。Spring Boot は Tomcat を内蔵して使っている

④ WARファイル ― 「Webアプリ用のJAR」

一言で言うと

Webアプリ専用のパッケージング形式 です。
JARとほぼ同じZIP形式ですが、WEB-INF/ などのWebアプリ固有のディレクトリ構造を含みます。

構造

myapp.war
├── WEB-INF/
│   ├── web.xml                     ← サーブレットの設定(古い形式)
│   ├── classes/                    ← .class ファイル
│   │   └── com/example/UserServlet.class
│   └── lib/                        ← 依存JARファイル
│       └── mysql-connector.jar
├── index.jsp
└── css/
    └── style.css

JAR / WAR / EAR の使い分け

形式 用途 中身
JAR 通常のJavaライブラリ・アプリ .class + リソース
WAR Webアプリ JAR + WEB-INF/ + 静的ファイル
EAR Enterprise Java(複数モジュール) JAR + WAR + 設定

Spring Boot は WAR ではなく「実行可能JAR」

# 昔のJava EEスタイル
$ mvn package          # → target/myapp.war
$ # Tomcatにデプロイ

# 現代のSpring Bootスタイル
$ mvn package          # → target/myapp.jar(実行可能JAR)
$ java -jar target/myapp.jar

Spring Boot の「実行可能JAR」は 内部にTomcatごと含む ため、サーバーに別途Tomcatをインストールする必要がありません。

よくある誤解

  • 「WAR と JAR は中身が違う」:構造は似ているが、WEB-INF/ の有無で区別される。
  • 「Spring Boot はWARを作る」:通常は JAR を作る。設定変更でWARも作れるが、新規案件ではほぼJAR。

⑤ フィルタ ― 「リクエスト前後の共通処理」

一言で言うと

サーブレットに到達する前 / 後に共通処理を挟む仕組み です。
認証、ログ、文字コード変換などに使います。

図解

[ブラウザ]
   ↓
[フィルタ1: 認証チェック]   ← 認証NGならここで弾く
   ↓
[フィルタ2: アクセスログ]
   ↓
[サーブレット / Controller]  ← 本処理
   ↓
[フィルタ2: レスポンス記録]
   ↓
[フィルタ1: ヘッダ追加]
   ↓
[ブラウザ]

リクエスト時は 上から下 に通り、レスポンス時は 下から上 に戻ります。

コード例(イメージ)

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;

public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, jakarta.servlet.ServletException {

        // 前処理(認証チェック)
        if (!isAuthenticated(req)) {
            // 認証NG → ここで止める(次のフィルタやサーブレットを呼ばない)
            return;
        }

        chain.doFilter(req, resp);  // ← 次のフィルタ or サーブレットへ

        // 後処理(レスポンスログなど)
    }

    private boolean isAuthenticated(ServletRequest req) {
        // 実装
        return true;
    }
}

chain.doFilter を呼ばないと 後続のサーブレットに到達しない のがポイント。これで「認証NGなら処理を弾く」が実現できます。

よくある用途

用途
認証 ログインしていないなら /login へリダイレクト
アクセスログ URL・IP・処理時間を記録
文字コード request.setCharacterEncoding("UTF-8")
CORS レスポンスヘッダに Access-Control-Allow-Origin を追加
圧縮 gzipで圧縮してレスポンス

よくある誤解

  • 「フィルタ = サーブレット」:違う。フィルタは 共通処理、サーブレットは 本処理
  • 「フィルタは1個しか付けられない」:複数チェインできる。順序は web.xml または @Order で制御。

⑥ Webコンテナ vs アプリケーションサーバー ― 用語の整理

新人が混乱しやすい区別です。

用語 範囲
Webコンテナ(サーブレットコンテナ) サーブレット仕様だけ実装 Tomcat、Jetty
アプリケーションサーバー サーブレット + EJB + JMS + JTA など Jakarta EE 全体 GlassFish、WildFly

新規案件では Spring Boot + Tomcat(Webコンテナのみ) が圧倒的多数。
GlassFish や WildFly のようなフルスタックは、大規模なエンタープライズ案件で残っている程度です。


⑦ ステートフル / ステートレス ― 状態を持つか持たないか

一言で言うと

用語 意味
ステートフル サーバーが前回のやり取りを覚えている セッションを使うログイン状態管理
ステートレス サーバーが何も覚えていない。毎回独立 REST API(トークンを毎回送る)

ステートフルの例(セッション)

// ログイン時
session.setAttribute("userId", 1234);

// 次のリクエスト
Long userId = (Long) session.getAttribute("userId");  // 覚えている

サーバー側にユーザーごとの状態(セッション)が保存されます。

ステートレスの例(JWT認証)

クライアント → サーバー
  Authorization: Bearer <JWTトークン>  ← 毎回送る

サーバーは JWT を検証するだけで、サーバー側に状態を保持しない

どちらを選ぶ?

観点 ステートフル ステートレス
スケーラビリティ △(同じユーザーは同じサーバーに送る必要) ◎(どのサーバーに送ってもOK)
実装の単純さ △(トークン管理が必要)
マイクロサービス向き

近年は マイクロサービス+ステートレス(JWT) がトレンドです。

よくある誤解

  • 「ステートフル = データベースを使う」:違う。状態は サーバーのメモリ(セッション) に持つ。DB保存とは別。
  • 「ステートレスならセッション不要」:その通り。ただし「ログイン状態の表現方法」は別途必要(JWT等)。

用語まとめ早見表

用語 一言で
サーブレット HTTPを処理するJavaクラス(Web版のmain)
JSP HTMLにJavaを埋め込むテンプレート(レガシー寄り)
Webコンテナ サーブレットを動かすサーバー(Tomcat等)
WARファイル Webアプリ用のJAR(WEB-INF/ を含む)
フィルタ サーブレットの前後に挟む共通処理(認証、ログ等)
アプリサーバー Webコンテナ + Jakarta EE 全体(GlassFish等)
ステートフル / ステートレス サーバーが状態を持つか持たないか

現場あるある誤解集

❌ 誤解 ⭕ 正しい理解
「Spring Boot は Tomcat を不要にした」 内蔵Tomcatで動いている
「JSP は今でも新規開発で使う」 新規ではほぼ使わない。Thymeleaf等に移行
「WAR と JAR は中身が全然違う」 構造は似ている。WEB-INF/ の有無で区別
「フィルタとサーブレットは同じ」 フィルタは共通処理、サーブレットは本処理
「Tomcat = サーバーOS」 Linux/Windows上で動くJavaプロセス
「ステートレス = データを持たない」 サーバー側に「状態」を持たないだけ。DBには持つ
「web.xml が必須」 Servlet 3.0以降は @WebServlet でアノテーション設定可

演習問題

問題1:Webコンテナとサーブレット ⭐

次の文章の空欄を埋めてください。

「ブラウザからHTTPリクエストが来ると、まず ___ がリクエストを受け取る。
その後、URLと対応する ___ にリクエストが渡され、Javaのコードが実行される。
___ では認証やログなどの共通処理を、本処理の前後に挟むことができる。」

模範解答

「ブラウザからHTTPリクエストが来ると、まず Webコンテナ(Tomcat等) がリクエストを受け取る。
その後、URLと対応する サーブレット にリクエストが渡され、Javaのコードが実行される。
フィルタ では認証やログなどの共通処理を、本処理の前後に挟むことができる。」

ポイント:「Webコンテナ → フィルタ → サーブレット」の流れを押さえる。Spring MVCも内部はこの仕組み。


問題2:JAR / WAR の使い分け ⭐

次のうち、WARファイル にパッケージングするのが適切なのはどれですか?

  • A. 数学計算ライブラリ(他のJavaプロジェクトから使う)
  • B. コマンドラインで動くバッチアプリ
  • C. ブラウザからアクセスするWeb管理画面
  • D. JUnit のテストランナー
模範解答

正解:C

解説

  • C はWAR:Webアプリなので WEB-INF/、サーブレット、JSP等が必要 → WARが適切
  • A、B、D はJAR:Web機能不要なので通常のJARで十分

ポイント:Spring Boot の新規案件では、Webアプリでも 実行可能JAR を作るのが主流。WARはレガシーや、外部Tomcatにデプロイする要件がある場合のみ。


問題3:ステートフル vs ステートレス ⭐

次のうち、ステートレス な設計はどれですか?

  • A. ログイン時にセッションにユーザーIDを保存し、次のリクエストで参照する
  • B. リクエストごとにJWTトークンを送り、サーバー側で検証する
  • C. サーバーのHashMapにユーザーごとのカート情報を保持する
  • D. ユーザーがログインすると、サーバー側のメモリに認証情報を記憶する
模範解答

正解:B

解説

  • B はステートレス:JWTを毎回送り、サーバー側は 何も覚えていない。検証だけする。
  • A、C、D は サーバー側がユーザーごとの状態を持っている ステートフル設計

ポイント:マイクロサービス・クラウドネイティブ時代では ステートレスがトレンド。複数サーバーで負荷分散しやすく、ある1台が落ちても他で処理を続けられる。


まとめ

Web/サーバー編の7用語のおさらいです。

  1. サーブレット:HTTPリクエストを処理するJavaクラス
  2. JSP:HTMLにJavaを埋め込むテンプレート(レガシー寄り)
  3. Webコンテナ(Tomcat等):サーブレットを動かすサーバー
  4. WARファイル:Webアプリ用のJAR(WEB-INF/ を含む)
  5. フィルタ:サーブレットの前後に挟む共通処理
  6. Webコンテナ vs アプリサーバー:仕様カバー範囲の違い
  7. ステートフル / ステートレス:状態を持つかどうか

Spring Boot を使っていても、内部はサーブレットの上に乗っている ことを理解しておくと、フレームワーク独自の動きにも対応しやすくなります。


次回予告

次回(#4)は 例外・スレッド編 です。

  • checked / unchecked 例外の使い分け
  • スレッド・synchronized・volatile
  • デッドロックとは何か

を解説します。


参考


@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?