本ページはプロモーションが含まれています

Java入門

Javaサーブレット入門 Webアプリの基礎を7ステップで解説

トム

・都内自社開発IT企業勤務/javaのバックエンドエンジニア
/java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎

私はこれまで10年以上にわたり、Javaを使ったシステム開発に携わってきました。駆け出しの頃、Javaサーブレットの概念を理解するのに苦労した経験があります。しかし、Spring Frameworkなどの便利なツールの裏側で、このサーブレットが力強く動いていると知ったとき、その重要性を痛感しました。

この記事は、過去の私と同じように「Javaサーブレットって何?」「Webアプリはどうやって動くの?」と疑問に思う初学者の方に向けて書いています。
この記事を最後まで読めば、あなたは以下の悩みを解決できます。

  • Javaサーブレットの基本的な役割と仕組みがわかる
  • 簡単なWebアプリケーションを自分で作れるようになる
  • 現代的なフレームワークを学ぶための強固な土台を築ける

Web開発の第一歩を、ここから一緒に踏み出しましょう。

Javaサーブレットとは?

Javaサーブレットは、Webアプリケーションの根幹をなす非常に重要な技術です。多くのフレームワークも、その内部ではサーブレットの仕組みを利用しています。まずは、このJavaサーブレットがどのようなもので、何をしているのかを理解していきましょう。

サーブレットの役割と仕組み

Javaサーブレットとは、ひとことで言うと「サーバー側で動くJavaプログラム」のことです。

Webブラウザからの要求(リクエスト)を受け取り、それに応じた処理を実行します。そして、結果として動的なWebページ(HTMLなど)を生成し、ブラウザに応答(レスポンス)を返す役割を担います。

この一連の流れは、以下のようになります。

  1. リクエスト: ユーザーがWebブラウザでURLにアクセスします。
  2. 受信: Webサーバーがそのリクエストを受け取ります。
  3. 処理依頼: Webサーバーは、リクエストに対応するJavaサーブレットを呼び出します。
  4. ビジネスロジック実行: サーブレットは、データベースへのアクセスや計算などの処理を実行します。
  5. レスポンス生成: 処理結果をもとに、動的にHTMLを生成します。
  6. 応答: 生成したHTMLをWebサーバー経由でブラウザに返します。

このように、Javaサーブレットはユーザーの見えないサーバー側で働き、Webページを動的に作り出す心臓部なのです。

JSPとの違いと関係性

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アプリケーションを公開できるのです。

サーブレットの基本的な実装

実際にJavaサーブレットをどのように実装するのか見ていきましょう。ここでは、基本となるクラスやメソッドについて解説します。コードの例を見ながら、具体的なイメージをつかんでください。

HttpServletクラスの継承

Javaサーブレットを作成するには、javax.servlet.http.HttpServletというクラスを継承する必要があります。このクラスには、Webアプリケーションで必要な機能があらかじめ用意されています。

HttpServletを継承することで、HTTPプロトコルに特化した処理を簡単に行えるようになります。自分で一から通信の仕組みを作る必要はありません。

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 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>");
}

doGetdoPostは、それぞれ異なる種類の要求に対応します。どちらのメソッドを実装するかは、アプリケーションの設計によって決まります。

リクエスト(HttpServletRequest)とレスポンス(HttpServletResponse)

doGetdoPostメソッドの引数に注目してください。HttpServletRequestHttpServletResponseという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にアクセスが来たら、このサーブレットを動かしてください」と教える必要があります。その設定方法と、アプリケーションを配備(デプロイ)する手順を見ていきましょう。

web.xml(deployment descriptor)の設定

古くから使われている設定方法が、web.xmlという設定ファイルを使う方式です。このXMLファイルに、サーブレットとURLの対応関係を記述します。

WEB-INFという特別なディレクトリの中にweb.xmlを配置します。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.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」クラスが実行されるようになります。

アノテーションによる設定方法(@WebServlet)

Servlet 3.0以降では、web.xmlを使わずに、もっと簡単に設定できる「アノテーション」という仕組みが導入されました。Javaクラスに直接、特別な目印(アノテーション)を付けることで設定が完了します。

@WebServletアノテーションを使うと、JavaコードだけでURLマッピングが可能です。

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
// ... 他のimport文

@WebServlet("/sample")
public class SampleServlet extends HttpServlet {
    // ... doGetやdoPostメソッドの実装
}

このように、クラス宣言の直前に@WebServlet("/sample")と記述するだけで、web.xmlに書いた設定と同じ意味になります。こちらの方が設定ファイルが不要で、コードが簡潔になるため、現在では主流の方法です。

WARファイルの作成とデプロイ

開発したWebアプリケーションをサーブレットコンテナで動かすには、所定の形式にまとめる必要があります。その形式がWAR(Web Application Archive)ファイルです。

WARファイルは、Javaクラス(.classファイル)、JSPファイル、HTMLファイル、画像、設定ファイル(web.xmlなど)を、特定のディレクトリ構造でZIP形式に圧縮したものです。

作成したWARファイルを、Tomcatのwebappsディレクトリに配置するだけで、Tomcatが自動的にファイルを展開し、アプリケーションが利用可能な状態になります。この作業を「デプロイ」と呼びます。

統合開発環境(IDE)のEclipseやIntelliJ IDEAを使えば、WARファイルの作成からデプロイまでを簡単に行えます。

サーブレットの応用と実践

Javaサーブレットの基本を理解したら、次はより実践的な使い方を見ていきましょう。データベースとの連携やフォームデータの処理は、多くのWebアプリケーションで必要となる機能です。

データベース連携(JDBC)

Webアプリケーションの多くは、商品情報やユーザー情報などをデータベースに保存しています。Javaサーブレットからデータベースにアクセスするには、JDBC(Java Database Connectivity)というAPIを利用します。

JDBCを使ったデータベース連携の一般的な手順は以下の通りです。

  1. JDBCドライバの読み込み: 使用するデータベース製品(MySQL, PostgreSQLなど)に応じたJDBCドライバをプロジェクトに追加し、読み込みます。
  2. データベースへの接続: 接続URL、ユーザー名、パスワードを指定して、データベースへの接続を確立します。
  3. SQL文の実行: PreparedStatementオブジェクトなどを用いて、SQL文(SELECT, INSERTなど)を作成し、実行します。
  4. 結果の処理: SELECT文の場合は、ResultSetオブジェクトから実行結果を取得し、処理します。
  5. リソースの解放: データベースとの接続や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アプリケーションの特定のイベント(ライフサイクルイベント)を検知して、処理を実行します。たとえば、アプリケーションの起動時にデータベース接続を初期化したり、セッションが作成されたときにログを記録したりするのに使われます。

これらの仕組みを活用すると、コードの重複を減らし、より構造化されたアプリケーションを構築できます。

サーブレットのセキュリティ

Webアプリケーションを公開する上で、セキュリティ対策は絶対に欠かせません。Javaサーブレットを開発する際にも、代表的な脆弱性とその対策を理解しておく必要があります。ここでは、特に重要な3つの脅威について解説します。

クロスサイトスクリプティング(XSS)対策

クロスサイトスクリプティング(XSS)は、悪意のあるユーザーがWebページに不正なスクリプトを埋め込み、他のユーザーのブラウザ上で実行させる攻撃です。これにより、個人情報が盗まれたり、意図しない操作をさせられたりする危険があります。

対策

ユーザーからの入力値を画面に出力する際には、必ず「エスケープ処理」を行います。エスケープ処理とは、<>といったHTMLタグとして特別な意味を持つ文字を、単なる文字列として表示されるように変換する(例: <&lt;に)処理です。

専用のライブラリ(例: OWASP Java Encoder)を使うことで、安全にエスケープ処理を実装できます。

SQLインジェクション対策

SQLインジェクションは、アプリケーションが想定していない不正なSQL文を、攻撃者によって実行されてしまう脆弱性です。これにより、データベース内の情報が盗まれたり、改ざん・削除されたりする可能性があります。

対策

SQL文を組み立てる際に、文字列連結で変数を埋め込むのは非常に危険です。必ず「プリペアードステートメント(PreparedStatement)」を使用してください。

PreparedStatementは、SQL文の骨格を先にデータベースに送り、後から値を「?」(プレースホルダ)の部分に安全な形で埋め込む仕組みです。これにより、入力値がSQL文の一部として解釈されるのを防ぎます。

セッションハイジャック対策

セッションハイジャックは、攻撃者が何らかの方法で他人のセッションIDを盗み出し、そのユーザーになりすまして不正な操作を行う攻撃です。

対策

  • 通信の暗号化(HTTPS): SSL/TLSを用いて通信全体を暗号化し、ネットワーク経路上でのセッションIDの盗聴を防ぎます。
  • セッションIDの再生成: ユーザーがログインに成功したタイミングなど、権限状態が変わる際には、request.changeSessionId()メソッド(Servlet 3.1以降)を呼び出して、セッションIDを新しいものに切り替えます。
  • 推測困難なセッションID: サーブレットコンテナが生成するセッションIDは十分に複雑ですが、自前で実装する場合は推測されないように注意が必要です。

これらの基本的なセキュリティ対策を怠ると、深刻な被害につながる可能性があります。安全なWebアプリケーション開発の基本として、必ず押さえておきましょう。

まとめ

Javaサーブレットは、現代のWebフレームワークを理解するための必須の基礎知識です。

なぜなら、SpringやJakarta EEといった高機能なフレームワークも、その内部ではサーブレットの技術が基盤として動いているからです。サーブレットがリクエストを受け取り、レスポンスを返すという基本的なサイクルを理解していると、フレームワークが裏側で何をしているのかを深くイメージできるようになります。

これにより、予期せぬエラーが発生した際のトラブルシューティング能力が格段に向上するでしょう。また、Webアプリケーションの根本的な仕組みを学ぶことで、特定のフレームワークに依存しない、応用力のある技術者へと成長できます。JavaでのWeb開発を志すなら、ぜひJavaサーブレットの学習から始めてみてください。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発IT企業勤務/javaのバックエンドエンジニア
/java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎

-Java入門