「Javaサーブレットって今でも学ぶ意味あるの?」「Spring Bootだけ覚えれば十分では?」——Web開発を始めたばかりだと、こう感じる方は多いはずです。結論から言うと、サーブレットはSpringもJakarta EEも内部で使い続けている「Web開発の心臓部」であり、ここを押さえると後続のフレームワーク学習が一気に速くなります。
私はJavaで10年以上の開発経験があり、駆け出しの頃にサーブレットでつまずいたからこそ、初心者がどこで詰まるかを把握しています。本記事では2026年最新(Jakarta EE 10 / Tomcat 10系)に対応した形で、サーブレットの仕組み・サンプルコード・Tomcatでの動かし方・セキュリティ対策までを7ステップで体系的に解説します。読み終えたら、以下の悩みが解決します。
- Javaサーブレットの基本的な役割と仕組みがわかる
- 簡単なWebアプリケーションを自分で作れるようになる
- 現代的なフレームワークを学ぶための強固な土台を築ける
Web開発の第一歩を、ここから一緒に踏み出しましょう。
Javaサーブレットとは?

Javaサーブレットは、Webアプリの根幹をなす重要な技術で、多くのフレームワークも内部でこの仕組みを利用しています。まずはサーブレットがどのようなもので何をしているのかを理解していきましょう。
サーブレットの役割と仕組み
Javaサーブレットとは、ひとことで言うと「サーバー側で動くJavaプログラム」のことです。
Webブラウザからの要求(リクエスト)を受け取り、それに応じた処理を実行します。そして、結果として動的なWebページ(HTMLなど)を生成し、ブラウザに応答(レスポンス)を返す役割を担います。
この一連の流れは、以下のようになります。
- リクエスト: ユーザーがWebブラウザでURLにアクセスします。
- 受信: Webサーバーがそのリクエストを受け取ります。
- 処理依頼: Webサーバーは、リクエストに対応するJavaサーブレットを呼び出します。
- ビジネスロジック実行: サーブレットは、データベースへのアクセスや計算などの処理を実行します。
- レスポンス生成: 処理結果をもとに、動的にHTMLを生成します。
- 応答: 生成したHTMLをWebサーバー経由でブラウザに返します。
このように、Javaサーブレットはユーザーの見えないサーバー側で働き、Webページを動的に作り出す心臓部なのです。
JSPとの違い・MVCモデルでの役割分担
Javaサーブレットとよく一緒に登場するのが、JSP(JavaServer Pages)です。両者は役割が異なりますが、協力してWebアプリケーションを構築します。
- Javaサーブレット: ロジックを記述するのが得意です。データベース連携や複雑な計算などを担当します。
- JSP: HTMLの中にJavaのコードを埋め込む形で、見た目を作るのが得意です。画面の表示デザインを担当します。
サーブレットのJavaコード内にHTMLをたくさん書くのは大変です。逆に、JSPに複雑なロジックを書くと見通しが悪くなります。そのため、処理はJavaサーブレット、表示はJSPというように役割分担するのが一般的です。これをMVC(Model-View-Controller)モデルと呼び、効率的な開発を可能にします。
サーブレットコンテナ(Tomcat)とは
作成したJavaサーブレットは、単体では動作しません。サーブレットを動かすためには、「サーブレットコンテナ」または「Webコンテナ」と呼ばれる特別なソフトウェアが必要です。
その代表例が、Apache Tomcatです。Tomcatは、サーブレットコンテナとして以下の重要な役割を果たします。
- サーブレットのライフサイクル管理: サーブレットの生成から破棄までを管理します。
- リクエストとレスポンスの管理: ブラウザからのリクエストを解析し、対応するサーブレットに渡します。また、サーブレットが生成したレスポンスをブラウザに返します。
- 通信の管理: HTTPプロトコルに基づいた通信を処理します。
簡単に言えば、Tomcatは「Javaサーブレットが快適に働くための実行環境」です。私たちはTomcatのようなコンテナに自作のサーブレットを配置(デプロイ)することで、Webアプリケーションを公開できるのです。
Tomcat 10系のインストール手順(macOS / Windows)
Apache Tomcatは公式サイト(tomcat.apache.org)から無料で入手できます。Jakarta EE 10対応の Tomcat 10.1系を選んでください(Tomcat 9系はjavax.servlet時代の最終版で、新規学習には10系を推奨)。
- macOS:
brew install tomcatが最短です。Homebrewが入っていれば1コマンドで導入でき、起動はbrew services start tomcat。 - Windows: 公式サイトから
apache-tomcat-10.1.x-windows-x64.zipをダウンロード→任意の場所に展開→bin\startup.batを実行。サービスとして登録するMSIインストーラもあります。 - 動作確認:
http://localhost:8080/にアクセスし、Tomcatのデフォルト画面が出れば成功。
サーブレットの基本的な実装

実際にJavaサーブレットをどのように実装するのか見ていきましょう。ここでは、基本となるクラスやメソッドについて解説します。コードの例を見ながら、具体的なイメージをつかんでください。
最小サーブレットを動かす7ステップ(Hello Worldを5分で)
タイトルにある「7ステップ」を最初に体験しておくと、以降のコード解説が腹落ちしやすくなります。Tomcat 10とJDK 17が手元にある前提で、最短ルートを示します。
- JDK 17以上をインストール:
java -versionで確認。 - Tomcat 10系をダウンロード: 公式サイトから
apache-tomcat-10.x.zipを取得し任意の場所に展開。 - プロジェクトフォルダを用意:
hello/WEB-INF/classes/とhello/WEB-INF/web.xmlを作成。 - HelloServlet.java を書く:
@WebServlet("/hello")付きクラスをWEB-INF/classes/配下に配置(パッケージなし)。 - コンパイル:
javac -cp "$CATALINA_HOME/lib/servlet-api.jar" HelloServlet.javaを実行。Tomcat 10ではjakarta.servletをインポートする点に注意。 - デプロイ:
helloフォルダごと$CATALINA_HOME/webapps/にコピー。 - 起動と確認:
$CATALINA_HOME/bin/startup.sh(Windowsはstartup.bat)で起動後、ブラウザでhttp://localhost:8080/hello/helloにアクセス。「Hello, Servlet!」が表示されれば完了。
この7ステップで動く最小単位を体験しておくと、続くHttpServlet継承やdoGetの説明が「あの動いた仕組みのこの部分か」と理解できるようになります。
HttpServletクラスの継承
Javaサーブレットを作成するには、jakarta.servlet.http.HttpServlet(Tomcat 9以前は javax.servlet.http.HttpServlet)というクラスを継承する必要があります。このクラスには、Webアプリケーションで必要な機能があらかじめ用意されています。
HttpServletを継承することで、HTTPプロトコルに特化した処理を簡単に行えるようになります。自分で一から通信の仕組みを作る必要はありません。
// Tomcat 10系(Jakarta EE 9以降)
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
// ※Tomcat 9以前を使う場合は import を javax.servlet.* に置き換える
public class SampleServlet extends HttpServlet {
// この中に処理を記述していく
}このように、クラス宣言でextends HttpServletと記述するのが、Javaサーブレット作成の第一歩です。
doGetメソッドとdoPostメソッド
HttpServletクラスを継承したら、次にdoGetメソッドやdoPostメソッドをオーバーライドして、具体的な処理を記述します。
- doGetメソッド: HTTPのGETリクエストを処理します。URLを直接入力したり、リンクをクリックしたりした場合に使われます。
- doPostメソッド: HTTPのPOSTリクエストを処理します。フォームからデータを送信する場合などによく利用されます。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// GETリクエストに対する処理をここに書く
response.setContentType("text/html; charset=UTF-8");
response.getWriter().println("<html><body><h1>Hello, World! (GET)</h1></body></html>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// POSTリクエストに対する処理をここに書く
response.setContentType("text/html; charset=UTF-8");
response.getWriter().println("<html><body><h1>Hello, World! (POST)</h1></body></html>");
}doGetとdoPostは、それぞれ異なる種類の要求に対応します。どちらのメソッドを実装するかは、アプリケーションの設計によって決まります。なお上記コードはTomcat 10系を想定しており、必要なimportは jakarta.servlet.* です(Tomcat 9以前なら javax.servlet.*)。
リクエスト(HttpServletRequest)とレスポンス(HttpServletResponse)
doGetやdoPostメソッドの引数に注目してください。HttpServletRequestとHttpServletResponseという2つのオブジェクトがあります。これらはJavaサーブレットにおいて非常に重要です。
- HttpServletRequest: ブラウザから送られてきた情報を持っています。
- フォームから送信された値の取得 (
getParameterメソッド) - リクエストURLやヘッダー情報の取得
- セッションやCookieの操作
- フォームから送信された値の取得 (
- HttpServletResponse: ブラウザに返す情報を設定します。
- 返すコンテンツの種類の指定 (
setContentTypeメソッド) - HTMLなどを書き出すための出力ストリームの取得 (
getWriterメソッド) - 別のページへリダイレクトする指示 (
sendRedirectメソッド)
- 返すコンテンツの種類の指定 (
例えば、フォームから送信された名前を取得して表示する場合、以下のように記述します。
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 送信された文字コードを設定
request.setCharacterEncoding("UTF-8");
// "username"という名前のフォーム要素の値を取得
String name = request.getParameter("username");
// レスポンスの準備
response.setContentType("text/html; charset=UTF-8");
// 画面に出力
response.getWriter().println("<html><body>こんにちは、" + name + "さん!</body></html>");
}このように、requestから情報を受け取り、responseを使って情報を返すのが基本です。
サーブレットの設定とデプロイ

Javaサーブレットのコードを作成したら、サーブレットコンテナに「このURLにアクセスが来たら、このサーブレットを動かしてください」と教える必要があります。その設定方法と、アプリケーションを配備(デプロイ)する手順を見ていきましょう。
javax.servlet → jakarta.servlet 移行ガイド(既存プロジェクトを更新する場合)
既存のサーブレットプロジェクトをTomcat 10系(Jakarta EE 10)にアップデートする際は、ソース全体の javax.servlet を jakarta.servlet に置換する作業が発生します。判断基準と移行手段を整理します。
- 新規プロジェクト: 迷わず Tomcat 10.1系 +
jakarta.servletを選ぶ。今後のJDK・フレームワーク更新と整合します。 - 既存プロジェクトの保守: 当面動かすだけなら Tomcat 9.0系 +
javax.servlet継続も選択肢。Tomcat 9はJakarta EE 8相当でセキュリティアップデートも継続しています。 - 移行する場合: IDE(IntelliJ IDEA / Eclipse)の「プロジェクト全体置換」で
javax.servlet→jakarta.servletを一括変換するのが基本。Apache公式のTomcat Migration Tool for Jakarta EEを使えば、コンパイル済みのWAR/JARを自動で書き換えることもできます。
注意点として、Spring Boot 3系もJakarta EE 9以降のみサポートし、Spring Boot 2.7系がjavax名前空間の最終バージョンです。フレームワーク側のメジャーアップデートと同時に移行するのが現実的です。
アノテーションによる設定方法(@WebServlet)
現在の主流は @WebServlet アノテーションを使う方式です。Servlet 3.0以降で導入され、設定ファイル不要でJavaコードだけでURLマッピングを完結できます。Jakarta EE 10ではパッケージが jakarta.servlet.annotation.WebServlet に変わっている点だけ注意してください。
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
// ... 他のimport文
@WebServlet("/sample")
public class SampleServlet extends HttpServlet {
// ... doGetやdoPostメソッドの実装
}クラス宣言の直前に@WebServlet("/sample")と書くだけで、web.xmlに書いていた設定と同じ意味になります。設定ファイルが要らずコードが簡潔になるため、新規プロジェクトはこちらが第一選択です。
web.xml(deployment descriptor)の設定
アノテーション登場以前から使われている設定方法が、web.xml を使う方式です。レガシーシステムや、外部から設定を切り替えたい場合に今も現役です。WEB-INFという特別なディレクトリの中にweb.xmlを配置します。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<!-- サーブレットの定義 -->
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>com.example.SampleServlet</servlet-class>
</servlet>
<!-- サーブレットとURLパターンのマッピング -->
<servlet-mapping>
<servlet-name>SampleServlet</servlet-name>
<url-pattern>/sample</url-pattern>
</servlet-mapping>
</web-app>この設定により「/sample」というURLへのアクセスがあった場合に、「com.example.SampleServlet」クラスが実行されます。Jakarta EE 10では web-app_6_0.xsd と名前空間 https://jakarta.ee/xml/ns/jakartaee を使う点に注意してください(Tomcat 9系までは http://xmlns.jcp.org/xml/ns/javaee の web-app_4_0.xsd)。
WARファイルの作成とデプロイ
開発したWebアプリケーションをサーブレットコンテナで動かすには、所定の形式にまとめる必要があります。その形式がWAR(Web Application Archive)ファイルです。
WARファイルは、Javaクラス(.classファイル)、JSPファイル、HTMLファイル、画像、設定ファイル(web.xmlなど)を、特定のディレクトリ構造でZIP形式に圧縮したものです。
作成したWARファイルを、Tomcatのwebappsディレクトリに配置するだけで、Tomcatが自動的にファイルを展開し、アプリケーションが利用可能な状態になります。この作業を「デプロイ」と呼びます。
統合開発環境(IDE)のEclipse・IntelliJ IDEA・Visual Studio Code(Java拡張)を使えば、WARファイルの作成からデプロイまでを簡単に行えます。
サーブレットとSpring Bootの違い・どちらを学ぶべきか
「いまから学ぶならSpring Bootだけで十分では?」とよく聞かれます。結論は 「Spring Bootを実務で使うとしても、サーブレットの基礎知識は必須」です。理由をまとめます。
- Spring Bootの内部はサーブレット: Spring MVCの
DispatcherServletはHttpServletを継承しており、フィルター・リスナー・HttpServletRequestはそのまま登場します。 - トラブルシュートで差が出る: 文字化け・セッション切れ・CORS・フィルター順序など、原因を追うときは結局サーブレット仕様の理解が要ります。
- 役割が違う: サーブレットは「HTTPを扱う最小APIの仕様」、Spring Bootは「サーブレット+多数のライブラリを束ねた開発フレームワーク」。比較というより階層関係です。
学習順は「サーブレットでHTTPの動きを把握 → Spring Bootで生産性を上げる」が最短ルートです。逆順で始めると、Springが裏で何をしているか分からないままアプリを書くことになり、エラー対応で詰まりがちになります。
サーブレットの応用と実践

基本を押さえたら、次はデータベース連携やフォームデータ処理といった実践的な使い方に進みましょう。多くのWebアプリで必要になる定番機能です。
データベース連携(JDBC)
多くのWebアプリは商品やユーザーの情報をデータベースに保存します。サーブレットからDBへアクセスするにはJDBC(Java Database Connectivity)というAPIを使います。
JDBCを使ったデータベース連携の一般的な手順は以下の通りです。
- JDBCドライバの読み込み: 使用するデータベース製品(MySQL, PostgreSQLなど)に応じたJDBCドライバをプロジェクトに追加し、読み込みます。
- データベースへの接続: 接続URL、ユーザー名、パスワードを指定して、データベースへの接続を確立します。
- SQL文の実行:
PreparedStatementオブジェクトなどを用いて、SQL文(SELECT, INSERTなど)を作成し、実行します。 - 結果の処理: SELECT文の場合は、
ResultSetオブジェクトから実行結果を取得し、処理します。 - リソースの解放: データベースとの接続や
PreparedStatementなどを、必ずclose()メソッドで解放します。
// 実際のコードではtry-with-resources文を使うのが一般的です
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1, 2. ドライバの読み込みと接続
Class.forName("com.mysql.cj.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/mydb", "user", "password");
// 3. SQL文の準備と実行
String sql = "SELECT id, name FROM users WHERE id = ?";
ps = con.prepareStatement(sql);
ps.setInt(1, 100);
rs = ps.executeQuery();
// 4. 結果の処理
if (rs.next()) {
String name = rs.getString("name");
// ...
}
} catch (Exception e) {
// エラー処理
} finally {
// 5. リソースの解放
// ...
}フォームデータの処理
HTMLのフォームから送信されたデータは、HttpServletRequestオブジェクトを使って受け取ります。request.getParameter("name属性値")メソッドで、テキストボックスやセレクトボックスなどの値を取得できます。
重要なのは、送信データの文字コードを正しく扱うことです。日本語などのマルチバイト文字を扱う場合、文字化けが発生することがあります。これを防ぐには、getParameterを呼び出す前に、request.setCharacterEncoding("UTF-8")を実行する必要があります。
// POSTリクエストの場合、最初に文字コードを設定
request.setCharacterEncoding("UTF-8");
// フォームから送信された値を取得
String name = request.getParameter("username");
String ageStr = request.getParameter("age");
String[] hobbies = request.getParameterValues("hobby"); // チェックボックスなど複数選択可能な場合
// 必要に応じて型変換やバリデーションを行う
int age = Integer.parseInt(ageStr);
// ... 取得したデータを使った処理フィルターとリスナー
サーブレットには、アプリケーション全体で共通の処理を行いたい場合に便利な「フィルター」と「リスナー」という仕組みがあります。
- フィルター: サーブレットがリクエストを処理する前後に、共通の処理を挟み込むことができます。すべてのリクエストに対して文字コードを設定したり、ログイン状態をチェックしたりするのに便利です。
- リスナー: Webアプリケーションの特定のイベント(ライフサイクルイベント)を検知して、処理を実行します。たとえば、アプリケーションの起動時にデータベース接続を初期化したり、セッションが作成されたときにログを記録したりするのに使われます。
これらの仕組みを活用すると、コードの重複を減らし、より構造化されたアプリケーションを構築できます。Tomcat 10系では jakarta.servlet.Filter / jakarta.servlet.ServletContextListener として実装します。
サーブレットのセキュリティ

Webアプリケーションを公開する上で、セキュリティ対策は絶対に欠かせません。Javaサーブレットを開発する際にも、代表的な脆弱性とその対策を理解しておく必要があります。ここでは、特に重要な3つの脅威について解説します。
クロスサイトスクリプティング(XSS)対策
クロスサイトスクリプティング(XSS)は、悪意のあるユーザーがWebページに不正なスクリプトを埋め込み、他のユーザーのブラウザ上で実行させる攻撃です。これにより、個人情報が盗まれたり、意図しない操作をさせられたりする危険があります。
SQLインジェクション対策
SQLインジェクションは、アプリケーションが想定していない不正なSQL文を、攻撃者によって実行されてしまう脆弱性です。これにより、データベース内の情報が盗まれたり、改ざん・削除されたりする可能性があります。
セッションハイジャック対策
セッションハイジャックは、攻撃者が何らかの方法で他人のセッションIDを盗み出し、そのユーザーになりすまして不正な操作を行う攻撃です。
サーブレットでよくあるエラーと対処
初学者が最初の数日で必ず踏むエラーをまとめておきます。原因と対処を1セットで覚えておくと、つまずきから抜け出すまでの時間が大幅に短くなります。
404 Not Found(URLにアクセスしても表示されない)
原因の多くは、@WebServletのURLパターンとアクセスURLの不一致、または webapps 配下のフォルダ名(コンテキストパス)の認識違いです。http://localhost:8080/<コンテキスト>/<URLパターン> という構造を意識しましょう。Tomcatのログ(logs/catalina.out)にデプロイ完了メッセージが出ているかも併せて確認します。
ClassNotFoundException / NoClassDefFoundError
Tomcat 10系で javax.servlet.* をインポートしているコードを動かすと発生する典型例です。Tomcat 10以降は jakarta.servlet.* のみ提供されるため、importを書き換えるか、Tomcat 9系(javax)に合わせる必要があります(詳細はPhase 3で解説するjavax→jakarta移行の項目を参照)。
フォーム送信で日本語が文字化けする
doPostの冒頭でrequest.setCharacterEncoding("UTF-8")を呼び忘れているケースが大半です。getParameterより前に必ず実行してください。レスポンス側もresponse.setContentType("text/html; charset=UTF-8")をセットします。
まとめ
Javaサーブレットは、現代のWebフレームワークを理解するための必須の基礎知識です。
なぜなら、SpringやJakarta EEといった高機能なフレームワークも、その内部ではサーブレットの技術が基盤として動いているからです。サーブレットがリクエストを受け取り、レスポンスを返すという基本的なサイクルを理解していると、フレームワークが裏側で何をしているのかを深くイメージできるようになります。
結果として、エラー時のトラブルシュート力が大きく上がります。Webアプリの根本を理解しておくと、特定フレームワークに依存しない応用力も身につくでしょう。JavaでのWeb開発を志すなら、ぜひサーブレットの学習から始めてみてください。
サーブレット学習の次のステップ
- JSPと組み合わせたMVCパターン: 画面生成をJSPに分離して保守性を上げる。
- Spring Boot: サーブレットの上に立つ生産性向上フレームワーク。実務では事実上の標準。
- Jakarta EE 10の他のAPI: CDI・JPA・JAX-RSなど。エンタープライズ開発の幅が広がる。
- HTTP/Cookie/CORSの仕様: サーブレットのリクエスト/レスポンスを深く扱うために必要。