結論から言うと、Javaサーブレットは、SpringもJakarta EEも内部で使い続けている「Web開発の心臓部」です。
「今でも学ぶ意味があるの?」と思うかもしれませんが、ここを押さえると後続のフレームワーク学習が一気に速くなります。
私もサーブレットでつまずいた経験があるからこそ、初心者がどこで詰まるかを把握しています。
最新のJakarta EE 11/Tomcat 11系に対応し、仕組み・サンプルコード・Tomcatでの動かし方・セキュリティ対策を7ステップにまとめました。
読み終えれば、以下の悩みが解決します。
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 11系のインストール手順(macOS / Windows)
Apache Tomcatは公式サイト(tomcat.apache.org)から無料で入手できます。
Jakarta EE 11対応の Tomcat 11.0系を選んでください(Tomcat 10.1系も現行サポート対象ですが、新規学習には最新の11.0系を推奨。
Tomcat 9系はjavax.servlet時代の最終版)。
- macOS:
brew install tomcatが最短です。Homebrewが入っていれば1コマンドで導入でき、起動はbrew services start tomcat。 - Windows: 公式サイトから
apache-tomcat-11.0.x-windows-x64.zipをダウンロード→任意の場所に展開→bin\startup.batを実行。サービスとして登録するMSIインストーラもあります。 - 動作確認:
http://localhost:8080/にアクセスし、Tomcatのデフォルト画面が出れば成功。
サーブレットの基本的な実装

実際にJavaサーブレットをどのように実装するのか見ていきましょう。ここでは、基本となるクラスやメソッドについて解説します。
コードの例を見ながら、具体的なイメージをつかんでください。
最小サーブレットを動かす7ステップ(Hello Worldを5分で)
タイトルにある「7ステップ」を最初に体験しておくと、以降のコード解説が腹落ちしやすくなります。
Tomcat 11とJDK 17以上が手元にある前提で、最短ルートを示します。
- JDK 17以上をインストール:
java -versionで確認。 - Tomcat 11系をダウンロード: 公式サイトから
apache-tomcat-11.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プロトコルに特化した処理を簡単に行えるようになります。自分で一から通信の仕組みを作る必要はありません。
クラス宣言でextends HttpServletと記述するのが、Javaサーブレット作成の第一歩です。
doGetメソッドとdoPostメソッド
HttpServletクラスを継承したら、次にdoGetメソッドやdoPostメソッドをオーバーライドして、具体的な処理を記述します。
- doGetメソッド: HTTPのGETリクエストを処理します。URLを直接入力したり、リンクをクリックしたりした場合に使われます。
- doPostメソッド: HTTPのPOSTリクエストを処理します。フォームからデータを送信する場合などによく利用されます。
doGetとdoPostは、それぞれ異なる種類の要求に対応します。どちらのメソッドを実装するかは、アプリケーションの設計によって決まります。
なお上記コードはTomcat 10系を想定しており、必要なimportは jakarta.servlet.* です(Tomcat 9以前なら javax.servlet.*)。
サーブレットのライフサイクル(init・service・destroy)
サーブレットには決まった生存期間(ライフサイクル)があり、サーブレットコンテナが以下の3つのメソッドを適切なタイミングで呼び出します。
- init(): 既定ではサーブレットが最初にリクエストを受けたときに1度だけ呼ばれる初期化処理です(
loadOnStartupを指定するとアプリケーション起動時に呼ばれます)。 - service(): リクエストのたびに呼ばれ、内部でHTTPメソッドに応じて
doGetやdoPostに処理を振り分けます。 - destroy(): サーブレットコンテナの終了時やアプリケーション停止時に1度だけ呼ばれる終了処理です。
サーブレットはコンテナ内で通常1つのインスタンスが使い回されるシングルトンとして動作します。
そのため、インスタンス変数(フィールド)への書き込みは複数のリクエストから同時にアクセスされる可能性があり、スレッドセーフではありません。
リクエストごとに変化する値は、インスタンス変数ではなくローカル変数として扱いましょう。
リクエスト(HttpServletRequest)とレスポンス(HttpServletResponse)
doGetやdoPostメソッドの引数に注目してください。
HttpServletRequestとHttpServletResponseという2つのオブジェクトがあります。
これらはJavaサーブレットにおいて重要です。
- HttpServletRequest: ブラウザから送られてきた情報を持っています。
- フォームから送信された値の取得 (
getParameterメソッド) - リクエストURLやヘッダー情報の取得
- セッションやCookieの操作
- フォームから送信された値の取得 (
- HttpServletResponse: ブラウザに返す情報を設定します。
- 返すコンテンツの種類の指定 (
setContentTypeメソッド) - HTMLなどを書き出すための出力ストリームの取得 (
getWriterメソッド) - 別のページへリダイレクトする指示 (
sendRedirectメソッド)
- 返すコンテンツの種類の指定 (
例えば、フォームから送信された名前を取得して表示する場合、以下のように記述します。
requestから情報を受け取り、responseを使って情報を返すのが基本です。
サーブレットの設定とデプロイ

Javaサーブレットのコードを作成したら、サーブレットコンテナに「このURLにアクセスが来たら、このサーブレットを動かしてください」と教える必要があります。
その設定方法と、アプリケーションを配備(デプロイ)する手順を見ていきましょう。
javax.servlet → jakarta.servlet 移行ガイド(既存プロジェクトを更新する場合)
既存のサーブレットプロジェクトをTomcat 10系(Jakarta EE 10)にアップデートする際は、ソース全体の javax.servlet を jakarta.servlet に置換する作業が発生します。
判断基準と移行手段を整理します。
- 新規プロジェクト: 迷わず Tomcat 11.0系 +
jakarta.servletを選ぶ(Jakarta EE 11対応)。今後の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 9以降ではパッケージが jakarta.servlet.annotation.WebServlet に変わっている点だけ注意してください。
クラス宣言の直前に@WebServlet("/sample")と書くだけで、web.xmlに書いていた設定と同じ意味になります。
設定ファイルが要らずコードが簡潔になるため、新規プロジェクトはこちらが第一選択です。
web.xml(deployment descriptor)の設定
アノテーション登場以前から使われている設定方法が、web.xml を使う方式です。レガシーシステムや、外部から設定を切り替えたい場合に今も現役です。
WEB-INFという特別なディレクトリの中にweb.xmlを配置します。
この設定により「/sample」というURLへのアクセスがあった場合に、「com.example.SampleServlet」クラスが実行されます。
Jakarta EE 11(Servlet 6.1)では上の例の web-app_6_1.xsd(version="6.1")、Jakarta EE 10(Servlet 6.0)では 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()メソッドで解放します。
フォームデータの処理
HTMLのフォームから送信されたデータは、HttpServletRequestオブジェクトを使って受け取ります。
request.getParameter("name属性値")メソッドで、テキストボックスやセレクトボックスなどの値を取得できます。
送信データの文字コードを正しく扱うことが重要です。日本語などのマルチバイト文字を扱う場合、文字化けが発生することがあります。
これを防ぐには、getParameterを呼び出す前に、request.setCharacterEncoding("UTF-8")を実行する必要があります。
フィルターとリスナー
サーブレットには、アプリケーション全体で共通の処理を行いたい場合に便利な「フィルター」と「リスナー」という仕組みがあります。
- フィルター: サーブレットがリクエストを処理する前後に、共通の処理を挟み込むことができます。すべてのリクエストに対して文字コードを設定したり、ログイン状態をチェックしたりするのに便利です。
- リスナー: 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)に合わせる必要があります(詳細は前述の「javax.servlet → jakarta.servlet 移行ガイド」を参照)。
フォーム送信で日本語が文字化けする
doPostの冒頭でrequest.setCharacterEncoding("UTF-8")を呼び忘れているケースが大半です。
getParameterより前に必ず実行してください。
レスポンス側もresponse.setContentType("text/html; charset=UTF-8")をセットします。
よくある質問
Q1. Javaサーブレットとは何ですか?
A1. サーバー側で動くJavaプログラムです。Webブラウザからのリクエストを受け取り、動的なWebページを生成してレスポンスを返す役割を担います。
Q2. サーブレットとJSPの違いは何ですか?
A2. サーブレットはロジック記述が得意でデータベース連携や複雑な計算を担当し、JSPはHTMLに埋め込む形で画面表示を担当します。処理はサーブレット、表示はJSPという役割分担がMVCモデルの基本です。
Q3. サーブレットを動かすには何が必要ですか?
A3. Tomcatなどのサーブレットコンテナ(Webコンテナ)が必要です。作成したサーブレットは単体では動作せず、コンテナに配置(デプロイ)することでWebアプリケーションとして公開できます。
Q4. javax.servletとjakarta.servletの違いは何ですか?
A4. サーブレットAPIを含むJava EEがOracleからEclipse Foundationへ移管されて「Jakarta EE」になり、Jakarta EE 9(2020年)でパッケージ名が変更されました。Jakarta EE 9以降はjakarta.servlet、それ以前(Jakarta EE 8を含む)はjavax.servletを使います。Tomcat 10系以降はjakarta名前空間のみサポートします。
Q5. doGetとdoPostはどう使い分けますか?
A5. doGetはURLへの直接アクセスやリンククリック時のGETリクエストを処理し、doPostはフォーム送信などのPOSTリクエストを処理します。アプリケーションの設計に応じて使い分けます。
Q6. サーブレットのインスタンス変数を使う際の注意点は?
A6. サーブレットは通常1つのインスタンスが使い回されるシングルトンとして動作するため、インスタンス変数への書き込みはスレッドセーフではありません。リクエストごとに変化する値はローカル変数として扱う必要があります。
Q7. URLにアクセスしてもサーブレットが表示されないのはなぜですか?
A7. 原因の多くは@WebServletのURLパターンとアクセスURLの不一致、またはwebapps配下のフォルダ名(コンテキストパス)の認識違いです。Tomcatのログにデプロイ完了メッセージが出ているかも確認してください。
Q8. ClassNotFoundExceptionが発生するのはなぜですか?
A8. Tomcat 10系でjavax.servlet.*をインポートしているコードを動かすと発生する典型例です。Tomcat 10以降はjakarta.servlet.*のみ提供されるため、importを書き換える必要があります。
Q9. フォーム送信で日本語が文字化けするのはなぜですか?
A9. 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の仕様: サーブレットのリクエスト/レスポンスを深く扱うために必要。
| REV. | DATE | 内容 |
|---|---|---|
| 4 | 2026-10-04 | 記載内容の事実確認と修正 |
| 3 | 2026-08-30 | 2026年8月時点の情報で全体を見直し(古い記述を6件更新) |
| 2 | 2026-04-26 | 2026年4月時点の情報で全体を見直し |
| 1 | 2025-10-21 | 初版 |

