サーブレット&JSPの基本|はじめてのサーブレット作成

Eclipseでサーブレットを作成し、アクセスするたびに変わるおすすめドリンクをJavaで表示してみよう

ここまでで、サーブレットの基本形、HTMLの出力方法、URLパターンの設定、そしてサーブレットの実行方法を学習してきました。次は、Eclipseを使って実際にサーブレットクラスを作成し、ブラウザから実行してみましょう。

今回作成するのは、アクセスするたびにおすすめドリンクがランダムに表示されるサーブレットです。飲み物の候補を配列で用意し、その中からJavaの乱数を使って1つを選びます。そして、その結果をHTMLとしてブラウザへレスポンスします。

プロジェクトは study、パッケージ名は servlet、クラス名は DrinkServlet とします。ファイル名もプログラムの内容に合わせて DrinkServlet.java にします。

Eclipseのサーブレット作成機能を使うと、サーブレットに必要なimport文、@WebServletアノテーション、HttpServletの継承、doGetメソッドなどの基本形を自動で作成できます。最初からすべてを手入力する必要はありません。

今回の作業では、自動生成されたサーブレットクラスを確認し、不要な初期処理を削除し、doGetメソッドの中にランダム表示とHTML出力の処理を追加していきます。

今回作成するサーブレットの全体像

今回作成するDrinkServletは、ブラウザからリクエストされると、いくつかのドリンク候補の中から1つをランダムに選びます。

選ばれたドリンク名と、ひとこと説明をHTMLに組み込み、Tomcatを通してブラウザへ返します。

URLパターンはクラス名と同じ /DrinkServlet にします。そのため、Tomcatを起動した状態で次のURLへアクセスすると、DrinkServletが実行されます。

http://localhost:8080/study/DrinkServlet

作成する内容

項目内容
プロジェクト名study
パッケージ名servlet
クラス名DrinkServlet
ファイル名DrinkServlet.java
URLパターン/DrinkServlet
表示内容ランダムに選ばれたおすすめドリンク
実行URLhttp://localhost:8080/study/DrinkServlet

実行結果は毎回同じとは限りません。ブラウザを更新したり、もう一度リクエストしたりすると、別のドリンクが表示されることがあります。

これにより、サーブレットがリクエストを受け取るたびにJavaの処理を実行し、結果に応じたHTMLを返していることを体験できます。

図1:DrinkServletで作成するランダムドリンク表示の全体像

この図から分かること

DrinkServletは、ブラウザからURLを指定して呼び出されます。ブラウザがhttp://localhost:8080/study/DrinkServletへアクセスすると、TomcatがURLパターン /DrinkServlet に対応するサーブレットクラスを探します。

対応するDrinkServletが見つかると、TomcatはdoGetメソッドを実行します。doGetメソッドの中では、ドリンク候補の中から1つをランダムに選び、その結果をHTMLとして出力します。

ブラウザに表示される画面は、あらかじめ作っておいたHTMLファイルではありません。リクエストを受け取ったタイミングで、サーブレットがJavaの処理を実行し、その場でHTMLを作成して返しています。

Eclipseでサーブレットクラスを作成する

まず、Eclipseでサーブレットクラスを新規作成します。

パッケージ・エクスプローラーで動的Webプロジェクト study を選択し、右クリックします。表示されたメニューから 新規 → その他 を選択します。

次に、表示された画面で Web → サーブレット を選択し、次へ をクリックします。

サーブレット作成の入口

手順操作
1パッケージ・エクスプローラーでstudyを選択する
2studyを右クリックする
3新規 → その他 を選択する
4Web → サーブレット を選択する
5次へ をクリックする

ここで通常のJavaクラスを選ばないように注意しましょう。通常のJavaクラスとして作成すると、@WebServletアノテーションやdoGetメソッドなど、サーブレットに必要な基本形が自動生成されません。

サーブレットとして動かしたいクラスを作成する場合は、Webカテゴリからサーブレットを選択します。

パッケージ名とクラス名を指定する

サーブレットの作成画面では、パッケージ名とクラス名を指定します。

今回は、パッケージ名を servlet、クラス名を DrinkServlet とします。

入力項目入力内容
パッケージservlet
クラス名DrinkServlet

パッケージは、Javaのクラスを整理するための入れ物です。サーブレットクラスをservletパッケージにまとめておくと、Webアプリケーションのリクエスト処理を担当するクラスだと分かりやすくなります。

クラス名は、処理内容が分かる名前にします。今回はおすすめドリンクを表示するサーブレットなので、DrinkServletという名前にします。

入力できたら、次へ をクリックします。

URLパターンを確認する

次の画面では、サーブレット名やURLパターンなどを確認します。

Eclipseでサーブレットクラスを新規作成すると、通常はクラス名に合わせてURLパターンが自動的に設定されます。

DrinkServletというクラス名で作成した場合、URLパターンは /DrinkServlet のように設定されます。

URLパターンの確認項目

項目内容
サーブレット名DrinkServlet
URLパターン/DrinkServlet
ブラウザで指定するURLhttp://localhost:8080/study/DrinkServlet

URLパターンは、ブラウザからサーブレットを呼び出すための名前です。

URLの最後にDrinkServlet.javaと書くのではなく、@WebServletで設定されたURLパターンを使います。今回であれば、URLの最後はDrinkServletになります。

自動作成するメソッドを選択する

次に、自動作成するメソッドを選びます。

基本的には、スーパークラスからのコンストラクターのチェックは外しておきます。そして、継承された抽象メソッドの中から、必要なメソッドにチェックを入れます。

今回使用するのはdoGetメソッドです。

メソッド選択で確認すること

項目対応
スーパークラスからのコンストラクター基本的にチェックを外す
doGetチェックを入れる
doPost今回は使用しない
完了設定を確認してクリックする

ブラウザにURLを入力してアクセスした場合や、リンクをクリックした場合は、通常GETリクエストになります。そのため、今回のサーブレットではdoGetメソッドを作成します。

doGetにチェックを入れて完了をクリックすると、src/main/javaの中にservletパッケージが作られ、その中にDrinkServlet.javaが作成されます。

図2:EclipseでDrinkServletを新規作成する手順

この図から分かること

Eclipseでサーブレットクラスを作成するときは、studyプロジェクトを右クリックし、Webカテゴリからサーブレットを選びます。

作成画面では、パッケージ名、クラス名、URLパターン、作成するメソッドを確認します。今回の例では、パッケージをservlet、クラス名をDrinkServlet、URLパターンを/DrinkServletとし、doGetメソッドを自動生成します。

この手順で作成すると、サーブレットに必要な基本的な記述をEclipseが用意してくれます。開発者は、自動生成されたdoGetメソッドの中へ必要な処理を追加していきます。

サーブレットクラスの作成手順

サーブレットクラスを作成する動的Webプロジェクトを選択して右クリック →「新規」→「その他」を選択します。

「Web」を展開して →「サーブレット」を選択し、「次へ」をクリックします。

サーブレットクラスが所属するパッケージに「servlet」、クラス名に「DrinkServlet」と入力、「次へ」をクリックします。

サーブレットの名前やURL マッピングといったサーブレットクラスに関する情報を設定します。デフォルトでは、サーブレットの名前に「クラス名」、URL マッピングは「/クラス名」が設定されています。「次へ」をクリックします。

「スーパークラスからのコンストラクター」のチェックを外し、「継承された抽象メソッド」の中から必要なメソッド、ここでは、「doGet」メッソドだけにチェックを入れて、「完了」をクリックします。

「src/main/java」内にサーブレットクラスが作成されます。

自動生成されたコードを確認する

サーブレットクラスの作成が完了すると、EclipseのエディタにDrinkServlet.javaが表示されます。

Eclipseでサーブレットを作成すると、サーブレットに必要な記述が自動で追加されます。たとえば、HttpServletを継承するクラス定義、@WebServletアノテーション、doGetメソッドなどです。

ただし、doGetメソッドの中に、初期表示用の処理が自動で書かれていることがあります。この処理は、サーブレットが作成できたことを簡単に確認するためのものです。

今回のように自分でHTMLを出力する処理を書く場合、この初期表示処理は不要です。残したままだと、意図しない文字がブラウザへ出力されたり、後から追加するHTMLと混ざって見づらくなったりすることがあります。

自動生成後に確認すること

確認項目内容
@WebServlet削除しない
URLパターン/DrinkServletになっているか確認する
doGet自動生成されているか確認する
初期表示処理不要なので削除する
コメント見づらい場合は整理してよい

コメントは残していても問題ありません。ただし、学習中にコードの見通しが悪くなる場合は、必要に応じて整理してもよいでしょう。

注意したいのは、@WebServletから始まる行を削除しないことです。この行がないと、TomcatがURLパターンとDrinkServletを結び付けられなくなります。

DrinkServlet.javaを完成させる

ここでは、ランダムにおすすめドリンクを選び、その結果をHTMLで返すDrinkServletを作成します。

Eclipseが自動生成したdoGetメソッドの中に、ドリンクをランダムに選ぶ処理、ひとこと説明を対応させる処理、HTMLを出力する処理を追加します。

おすすめドリンクをHTMLでレスポンスするサーブレットクラスの例

ファイル名: DrinkServlet.java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/DrinkServlet")
public class DrinkServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {

        // おすすめドリンクをランダムで決定
        String[] drinkArray = {
                "アイスコーヒー",
                "レモンティー",
                "ミネラルウォーター",
                "抹茶ラテ"
        };

        String[] commentArray = {
                "集中して作業したいときにおすすめです",
                "気分を切り替えたいときにぴったりです",
                "すっきりしたいときに向いています",
                "少し休憩したいときにおすすめです"
        };

        int index = (int) (Math.random() * drinkArray.length);
        String drink = drinkArray[index];
        String comment = commentArray[index];

        // HTMLを出力
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html>");
        out.println("<head>");
        out.println("<meta charset=\"UTF-8\" />");
        out.println("<title>おすすめドリンク</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>今日のおすすめドリンク</h1>");
        out.println("<p>おすすめは「" + drink + "」です。</p>");
        out.println("<p>" + comment + "</p>");
        out.println("</body>");
        out.println("</html>");
    }
}

ブラウザの表示例

このサーブレットでは、drinkArrayにおすすめドリンクを、commentArrayにそれぞれの説明文を用意しています。

Math.randomを使って配列の添字をランダムに決め、その添字を使ってドリンク名と説明文を取り出します。drinkArrayとcommentArrayで同じ添字を使うことで、選ばれたドリンクに対応した説明文を表示できます。

@WebServletとURLパターン

DrinkServlet.javaでは、次の行でURLパターンを設定しています。

@WebServlet("/DrinkServlet")

Eclipseでサーブレットクラスを新規作成すると、URLパターンには/クラス名が自動的に設定されます。今回のクラス名はDrinkServletなので、URLパターンは/DrinkServletです。

そのため、ブラウザから実行するときのURLは次のようになります。

http://localhost:8080/study/DrinkServlet

URLパターンの対応

項目内容
プロジェクト名study
クラス名DrinkServlet
URLパターン/DrinkServlet
実行URLhttp://localhost:8080/study/DrinkServlet

URLパターンを変更したい場合は、@WebServletの中を手動で書き直します。

ただし、クラス名を変更しても、@WebServletのURLパターンが自動で変更されるとは限りません。既存のサーブレットクラスをコピーして作成した場合も、コピー元のURLパターンが残ることがあります。

サーブレットクラス名とURLパターンは別のものなので、作成後には必ず確認しましょう。

URLパターンの重複に注意する

同じ動的Webプロジェクト内で、複数のサーブレットに同じURLパターンを設定してはいけません。

たとえば、別のサーブレットにも@WebServlet("/DrinkServlet")を設定してしまうと、Tomcatはどちらのサーブレットを実行すればよいか判断できません。

その結果、サーバーが起動しなかったり、実行時にエラーになったりすることがあります。

URLパターンで注意すること

注意点内容
/から始めるURLパターンは/DrinkServletのように指定する
重複させない同じプロジェクト内で同じURLパターンを複数使わない
クラス名変更時に確認するクラス名を変えてもURLパターンは自動変更されない
コピー作成時に確認するコピー元と同じURLパターンが残りやすい

サーブレットが増えてくると、URLパターンの管理が大切になります。どのURLでどのサーブレットが動くのかを整理しておくと、実行時の混乱を防ぎやすくなります。

serialVersionUIDフィールド

Eclipseでサーブレットクラスを作成すると、次のようなフィールドが自動的に定義されることがあります。

private static final long serialVersionUID = 1L;

これは、Javaのシリアライズという仕組みに関係する識別番号です。サーブレットの基本学習では、深く意識する必要はありません。

Eclipseが自動で作成した場合は、そのまま残しておいて問題ありません。

記述学習上の扱い
serialVersionUID基本学習では深く考えなくてよい
自動生成された場合そのまま残してよい
削除した場合警告が出る場合がある

ここでは、DrinkServletの中心はdoGetメソッドの中身であると考えましょう。

ランダムなドリンクを決める処理

今回のプログラムでは、drinkArrayという配列に4つのドリンク名を用意しています。

さらに、commentArrayという配列に、それぞれのドリンクに対応する説明文を用意しています。

Math.randomは、0以上1未満の小数を返します。これにdrinkArray.lengthを掛けることで、配列の要素数に合わせた範囲の値を作れます。

さらにint型に変換すると、小数部分が切り捨てられ、配列の添字として使える整数になります。

ランダムな添字を作る流れ

処理結果
Math.random0以上1未満の小数
Math.random() * drinkArray.length0以上drinkArray.length未満の小数
int型へ変換0からdrinkArray.length - 1までの整数

今回の配列には4つのドリンクが入っているため、indexには0、1、2、3のいずれかが入ります。

添字ドリンク説明文
0アイスコーヒー集中して作業したいときにおすすめです
1レモンティー気分を切り替えたいときにぴったりです
2ミネラルウォーターすっきりしたいときに向いています
3抹茶ラテ少し休憩したいときにおすすめです

同じindexを使ってdrinkArrayとcommentArrayから値を取り出しているため、ドリンク名と説明文の組み合わせがずれません。

HTMLを出力する処理

DrinkServlet.javaの後半では、ブラウザへ返すHTMLを作成しています。

最初に、Content-Typeを設定します。

response.setContentType("text/html; charset=UTF-8");

この記述によって、ブラウザへ返す内容がUTF-8のHTMLであることを知らせます。

次に、response.getWriterでPrintWriterを取得します。

PrintWriter out = response.getWriter();

そのあと、out.printlnを使ってHTMLを1行ずつ出力します。

HTML出力の流れ

順番処理
1response.setContentTypeでHTMLと文字コードを指定する
2response.getWriterでPrintWriterを取得する
3out.printlnでHTMLを出力する

サーブレットでHTMLを出力するときは、この順番が基本です。

Content-Typeの設定を先に行い、そのあとPrintWriterを取得し、HTML本文を書き込んでいきます。

metaタグの二重引用符に注意する

HTML内のmetaタグでは、charset属性にUTF-8を指定しています。

Javaの文字列は二重引用符で囲みます。そのため、文字列の中でHTML属性の二重引用符を出力したい場合は、二重引用符の前にバックスラッシュを付けます。

今回の例では、次の行が該当します。

out.println("<meta charset="UTF-8" />");

Javaのソースコードではバックスラッシュが表示されますが、ブラウザへ送られるHTMLでは通常の二重引用符として扱われます。

環境によっては、バックスラッシュが円記号のように表示されることがあります。見た目が違っても、文字列内の二重引用符を表すという意味は同じです。

図3:DrinkServletの実行結果と500ページ

この図から分かること

DrinkServletが正常に実行されると、ブラウザにはランダムに選ばれたおすすめドリンクと、そのドリンクに対応する説明文が表示されます。

ブラウザを更新したり、もう一度実行したりすると、別のドリンクが表示されることがあります。これは、リクエストのたびにdoGetメソッドが実行され、その中でランダムな値を作っているためです。

一方、サーブレットの実行中に例外が発生すると、TomcatはHTTPステータス500のエラーページを返します。500ページは、サーバー内部で処理中に問題が発生したことを表します。

DrinkServletを実行する

DrinkServlet.javaが完成したら、ファイルを保存して実行します。

Eclipseでは、保存時に自動でコンパイルが行われます。ソースコードにエラーがなければ、Tomcatで実行できる状態になります。

実行する方法は、ブラウザにURLを入力する方法と、Eclipseの実行機能を使う方法があります。

方法1 ブラウザにURLを入力する

Tomcat11(Java25)を起動した状態で、ブラウザのアドレスバーに次のURLを入力します。

http://localhost:8080/study/DrinkServlet

正しく実行されると、次のような内容が表示されます。

今日のおすすめドリンク

おすすめは「アイスコーヒー」です。

集中して作業したいときにおすすめです

表示されるドリンクはランダムなので、実行するたびに別の内容になることがあります。

方法2 Eclipseの実行機能を使う

パッケージ・エクスプローラーでDrinkServlet.javaを選択し、右クリックします。

表示されたメニューから 実行 → サーバーで実行 を選択します。使用するサーバーにはTomcat11(Java25)を選びます。

設定に問題がなければ、ブラウザが起動し、DrinkServletの実行結果が表示されます。

実行前に確認すること

確認項目内容
プロジェクトstudyを使用している
クラスservletパッケージ内のDrinkServlet.java
URLパターン/DrinkServlet
TomcatTomcat11(Java25)が起動している
URLhttp://localhost:8080/study/DrinkServlet
保存DrinkServlet.javaを保存している

サーブレットを実行できない場合は、まずURLと@WebServletの指定が一致しているかを確認しましょう。

500ページが表示された場合

サーブレットを実行したときに、HTTPステータス500と表示されたエラーページが出ることがあります。

500ページは、サーバー内部で処理中に問題が発生したことを示しています。サーブレットの場合、多くはJavaの例外が原因です。

たとえば、配列の添字を間違えたり、必要な処理を書き忘れたりすると、実行中に例外が発生することがあります。その場合、Tomcatは通常のHTMLレスポンスを返せず、500ページを表示します。

500ページが出たときに見る場所

確認場所見る内容
ブラウザのエラーページHTTPステータス500、例外名、メッセージ
Eclipseのコンソール例外の詳しい内容
DrinkServlet.javaエラーが発生している行
import文必要なクラスが読み込まれているか
doGet内の処理配列、添字、文字列連結などに誤りがないか

500ページが表示された場合は、ブラウザの表示だけでなく、Eclipseのコンソールも確認します。コンソールには、どのクラスのどの行で問題が発生したのかが表示されることがあります。

エラーが出たときは、まず例外名とエラー行を確認しましょう。エラーページは失敗を知らせるだけでなく、修正の手がかりにもなります。

作成時に気をつけたいポイント

サーブレットクラスを作成するときは、URLパターン、自動生成された処理、doGetメソッド、HTML出力の順番を確認しましょう。

注意点内容
@WebServletを削除しないURLパターンで呼び出せなくなる
URLパターンを重複させないTomcat起動時のエラーにつながる
不要な初期表示処理を削除する自分で作成するHTML出力と混ざるのを防ぐ
doGetに処理を書くURL入力やリンククリックではdoGetが実行される
Content-Typeを先に設定するHTML出力前に文字コードを指定する
PrintWriterを使うブラウザへHTMLを返すために必要
配列の添字に注意する配列の範囲外を指定するとエラーになる
import文を確認するPrintWriterなどが必要になる

Eclipseはサーブレットの基本形を自動で作ってくれるため、とても便利です。ただし、自動生成された内容をそのまま使うだけではなく、どの部分を残し、どの部分を削除し、どこに処理を追加するのかを確認しながら進めることが大切です。

今回のDrinkServletでは、doGetメソッドの中でランダムな値を作り、配列からおすすめドリンクを選び、HTMLとしてブラウザへ返しました。この流れが、サーブレットで動的なWebページを作成する基本になります。