【Java Web入門 #2】サーブレットの作成|サーブレットコンテナを動かしてみよう
2024.12.13
前回の記事(【Java Web入門 #1】Webアプリケーションとは)では、JavaでWebアプリケーションを作成するための仕組みである「サーブレット」について簡単にご紹介しました。
今回の記事では、実際にパソコン上にWebアプリケーションの開発環境を作成して、サーブレットを動作させる手順についてご紹介します。
目次
サーブレットコンテナ
サーブレットコンテナとは
前回、サーブレットでは「インターネットを通じた要求(リクエスト)を受け取り、Javaで記述したプログラムを実行して、動的に要求元へ結果を返却(レスポンス)する」とお伝えしました。
このとき「要求(リクエスト)を受け取り」「要求元へ結果を返却(レスポンス)する」働きを担うのが、サーブレットコンテナ(Webコンテナ)と呼ばれるソフトウェアです。
サーブレットコンテナは、Webブラウザなどから送られてきたリクエストを受け取り、どのサーブレットの処理を行うかを判断して、そのサーブレットを呼び出します。
そしてサーブレットが処理を終えると、その結果を要求元(クライアント)に対してレスポンスとして返す、という橋渡し役をサーブレットコンテナが担っています。
主なサーブレットコンテナ
サーブレットコンテナには色々な種類のものがありますが、無償で利用できる主なサーブレットコンテナをいくつかご紹介します。
- Tomcat
Apache Tomcatは、Webサーバーとして有名なApacheソフトウェア財団が提供するサーブレットコンテナであり、最も利用されているサーブレットコンテナです。
Java版のPleiades(日本語版Eclipse統合環境)にもデフォルトのサーブレットコンテナとして同梱されており、追加ダウンロード不要ですぐに利用することができます。
- Apache Tomcat 公式サイト(英語) - Jetty
JettyはWebtide社によって開発されたサーブレットコンテナで、2009年からはコアコンポーネントがEclipse財団に移管されました。
軽量でシンプルなサーブレットコンテナとして開発されていますが、Google App Engineのような大規模サービスでも利用されています。
- Eclipse Jetty 公式サイト(英語) - GlassFish
GlassFishはJavaの開発元であったサン・マイクロシステムズを中心としたオープンソースコミュニティによって開発が始まったサーブレットコンテナです。
Oracle社を経て2017にEclipse財団に寄贈され、現在は主に開発者向けの参照実装として開発が進められています。
- Eclipse GlassFish 公式サイト(英語)
サーブレットのローカル開発環境作成(Eclipse+Tomcat)
サーバーの確認
Webアプリケーションを作成する前に、Eclipseのパースペクティブを「Web」に切り替えます。(右上の地球のアイコンをクリック)
「Web」パースペクティブが表示されていない場合は、メニューから「ウィンドウ」>「パースペクティブ」>「パースペクティブを開く」>「新規」の順に選択して、「Web」を選択します。
(または、右上のパースペクティブを開くアイコンから「Web」を選択します)
(「Web」を選択)
サーバー・ビューで、Eclipseにインストール済のサーブレットコンテナ(Tomcat)を確認します。サーバー・ビューが表示されていない場合は、メニューから「ウィンドウ」>「ビューの表示」>「サーバー」を選択して表示します。
サーバー・ビュー上で、お使いのEclipse環境で利用できるサーバー(サーブレットコンテナ)が確認できました。Webアプリケーションを動作させるサーバーを選択し、右クリック>「開始」をクリックして、サーブレットコンテナを起動してみましょう。ここでは「Tomcat10_Java21」を起動してみます。
※Tomcatを初めて起動する場合、Windowファイアウォールの確認メッセージが表示される場合がありますので、通信を許可してください。
コンソール・ビューにTomcatの起動時のログが出力された後、対象のサーバーが「起動済み, 同期済み」となれば起動完了です。
Tomcatが起動したら、Webブラウザで以下のURLにアクセスしてみましょう。
http://localhost:8080/
下図の画面が表示されたら、Tomcatは正常に動作しています。(内容はエラー画面の表示ですが、表示するコンテンツの作成前ですので問題ありません)
(参考)サーバーを追加したい場合
利用したいサーバーが一覧に表示されない場合は、以下の手順で追加することもできます。
別バージョンのTomcatを追加
サーバービュー上でマウスを右クリックし、表示されるメニューから「新規」>「サーバー」の順に選択して「新規サーバーの定義」画面を開き、「apache」のフォルダから追加したいバージョンのTomcatを選択して追加します。
(追加するTomcatのバージョンを選択)
Jettyを追加
Eclipseの上部メニューから「ヘルプ」>「マーケットプレース」の順に選択し、マーケットプレースの画面上から「Jetty」で検索を行います。
「Eclipse Jetty」プラグインをインストールすることで、Eclipse上でGlassFishを利用することが可能となります。
GlassFishを追加
Jettyと同様にマーケットプレースから「GlassFish」で検索し、「GlassFish Tools」プラグインをインストールすることで、Eclipse上でGlassFishを利用することが可能となります。
プロジェクトの作成
Webアプリケーションのプロジェクトを作成するには、Eclipseの上部メニューの「ファイル」から、「新規」>「動的Webプロジェクト」の順に選択します。
動的Webプロジェクトの作成画面でプロジェクト名を入力します。ここでは「WebPractice」としています。
他の項目はデフォルトの設定のままで問題ありませんが、「ターゲット・ランタイム」に、利用したいサーブレットコンテナとJavaバージョンが選択されているか確認してください。ここでは「Tomcat10(Java21)」を選択しています。
確認できたら、下部の「次へ」をクリックします。
ビルド・パス上のソースフォルダー(ソースコードの格納先フォルダ)の指定画面が表示されます。この画面では特に変更は不要です(デフォルトの「src\main\java」フォルダが設定されていればOKです)ので、再度「次へ」をクリックします。
Webモジュールの設定画面が表示されます。コンテキスト・ルートは、作成するWebアプリケーションにアクセスするためのURL(「http://localhost:8080/」に続けて入力する部分)の定義ですが、ここではデフォルト(プロジェクト名と同一)のままでOKです。
次に、「web.xmlデプロイメント記述子の生成」にチェックを付けてください。
※このチェックを付けておくことで、サーブレットの定義などが自動化されます。以降の手順はここにチェックを付けた前提となりますのでご注意ください。
確認できたら、最後に「完了」ボタンをクリックして作成完了です。
プロジェクト・エクスプローラー上に作成したプロジェクトが表示されました。
サーブレットの作成
Webアプリケーション内に、実際に動かすプログラムであるサーブレットのクラスを作成します。
クラスの作成の前に、ソースフォルダー(/src/main/java)内にパッケージを作成しましょう。パッケージはソースフォルダー上で右クリック>「新規」>「その他」から、「Java」フォルダ内の「パッケージ」を選択して追加できます。
ここではパッケージ名を「site.knovus.example」として作成しました。
(「Java」フォルダ内の「パッケージ」を選択)
(パッケージを作成)
作成されたパッケージ内のexampleフォルダ内に、クラスを作成します。右クリック>「新規」>「その他」から、「Web」フォルダ内の「サーブレット」を選択します。(この手順で作成することで、サーブレットを動かすための設定も自動的に生成されます)
(「Web」フォルダ内の「サーブレット」を選択)
ここではクラス名を「FirstServlet」として作成します。「完了」ボタンをクリックすると、基本的な構成のサーブレットのクラスが作成されます。
(作成されるクラスの内容 ※Eclipseの設定により異なる場合があります)
package site.knovus.example;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Servlet implementation class FirstServlet
*/
public class FirstServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public FirstServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
実行時にFirstServletクラスで処理された結果であることがわかるように、ひとまずdoGetメソッドだけ編集しておきます。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter()
.append("Served at: ")
.append(request.getContextPath())
.append("/FirstServlet");
}
これで最初のサーブレットを実行する準備は完了です。
サーブレットの実行
Tomcatへの配備と起動
作成したWebアプリケーション(動的Webプロジェクト)を動作させるサーバーを選択します。プロジェクト・エクスプローラー上で配備するプロジェクトのフォルダ(WebPractice)を右クリックし、「実行」>「サーバーで実行」をクリックします。
一覧からWebアプリケーションを配備するサーバーを選択して、「完了」ボタンをクリックすると対象のサーバーが起動します。
このとき、設定にエラーがある場合などはサーバーの起動に失敗する場合がありますので、Tomcatの起動ログの出力後、対象のサーバーが「起動済み, 同期済み」となっていることを確認してください。
※一度アプリケーションの配備が成功したら、以降はサーバー・ビュー上で対象のサーバーを右クリックし、「開始」を選択して起動できます。
Webブラウザからのアクセス
URLを直接入力してアクセスした場合は、doGetメソッドが呼び出されます。
お使いのWebブラウザに、以下のURLを直接入力して、作成したサーブレットにアクセスします。
http://localhost:8080/WebPractice/FirstServlet
サーブレットの実行結果が表示されました。
web.xmlとサーブレットの設定
プロジェクトのフォルダーを見ると、ソース・フォルダーに指定したフォルダー(/src/main/java)以外に、webapp(/src/main/webapp)というフォルダーが作成されていると思います。
このフォルダーは、Webアプリケーションの設定ファイルや利用するライブラリなどを格納するためのフォルダーで、特にWEB-INFフォルダ内のweb.xmlというファイルは特別な役割を持ちます。
web.xmlとは
web.xmlは、JavaのWebアプリケーションにおいて、サーブレットコンテナに対しWebアプリケーションの設定を伝える役割を持ちます。
例えば、このWebアプリケーションに定義されているサーブレットの一覧や、エラー時に表示すべきファイル、HTTPセッションの有効期限やフィルター処理など、サーブレットコンテナがこのWebアプリケーションを動作させる上で必要な情報を定義することができます。
サーブレットの設定
サーブレットコンテナがサーブレットを動かすために、クラスの情報や、どのURLで動作させるかなどの情報をweb.xmlに定義することができます。
サーブレットの定義
web.xmlには、このWebアプリケーションで動作させるサーブレットの名前とクラスを定義します。試しに、FirstServletクラスの作成手順と同じ手順で、SecondServletクラスを作成してみましょう。
この時、web.xmlには以下の項目(<servlet>~</servlet>)が追加されます。(※Eclipseの設定によって異なる場合がありますのでご注意ください)
<servlet>
<description></description>
<display-name>SecondServlet</display-name>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>site.knovus.example.SecondServlet</servlet-class>
</servlet>
これは、「SecondServlet」という名前(servlet-name)で、「site.knovus.example.SecondServlet」を動作させるクラス(servlet-class)とするサーブレットを定義しています。(省略可能な2つの要素(descriptionとdisplay-name)については割愛します)
サーブレットマッピングの定義
上記の手順でSecondServletを作成した場合は、web.xmlにはサーブレットマッピング(servlet-mapping)も同時に追加されています。
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/SecondServlet</url-pattern>
</servlet-mapping>
サーブレットマッピングとは、「どのURLにアクセスしたら」「どのサーブレットを呼び出す」組み合わせの定義です。
上記の例では、「 /SecondServlet」というURL(url-pattern)にアクセスした際に、「SecondServlet」という名前(servlet-name)で定義されているサーブレットを呼び出す、という組み合わせが定義されています。
サーブレットマッピングの定義では、異なるurl-patternに対して同じサーブレット(servlet-name)を定義することができますが、同じurl-patternに対して異なるサーブレットを定義することはできません。
(URLに対して動作するサーブレットが一意である必要がある)
では、実際にマッピングの通りに処理が呼び出されるか試してみます。どのサーブレットが呼び出されたか判別できるように、作成したSecondServlet.javaのdoGetメソッドを編集します。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter()
.append("Served at: ")
.append(request.getContextPath())
.append("/SecondServlet <- new!");
}
上記のとおり実装したら、サーバー・ビュー上でWebアプリケーションを配備したサーバーを再起動してください。(右クリック>「停止」を選択して停止後に、右クリック>「開始」をクリックして、再度サーブレットコンテナを起動してください)
サーブレットコンテナが起動されたら、web.xmlの設定に従って、以下のURLでWebアプリケーションにアクセスしてみましょう。
http://localhost:8080/WebPractice/SecondServlet
アノテーションを用いたサーブレットの定義
バージョン3.0以降のサーブレット(Tomcatは7.0以降で対応)では、サーブレットやサーブレットマッピングの定義を、xmlを用いずに、アノテーションという記法でプログラム上に直接設定することもできます。
アノテーションとは
アノテーションとは、ソースコードに注釈を付けることで、コンパイラやツールなどに対して指示を与えることができる仕組みです。
クラスやインターフェイス、メソッド、変数などの宣言の直前に「@」で始まる特定のキーワードを記述することで、属性などを明記しておくことでコーディングのサポートを行ったり、機能を付加したりすることができます。
例としては、メソッドが基底クラスのメソッドのオーバーライドであることを示す「@Override」や、メソッドが非推奨であることを示す「@Deprecated」などが挙げられます。
// Overrideアノテーション
@Override
public String toString() { ...
// Deprecatedアノテーション
@Deprecated
public void oldMethod() { ...
アノテーションでサーブレットを定義
サーブレットの基底クラスである「HttpServlet」を継承したクラスでは、サーブレットの定義を「@WebServlet」アノテーションを用いて、サーブレットの定義をクラスの作成時に宣言することができます。
以下の例では、「/second」「/2nd」という2つのURLのパターンに対して、SecondServletクラスを動作するサーブレットとして定義しています。
// WebServletアノテーションを利用するためのクラスがインポートされていない場合は追加
import jakarta.servlet.annotation.WebServlet;
// クラスの宣言の前にWebServletアノテーションを追加
@WebServlet(name="SecondServlet", urlPatterns = {"/second", "/2nd"})
public class SecondServlet extends HttpServlet { ...
このようにアノテーションを定義した場合、web.xmlにサーブレットおよびサーブレットマッピングの定義がなくても、アノテーションで指定したURLにアクセスすることで、サーブレットを動作させることができます。
web.xml上の定義をコメントアウトして試してみます。xmlのコメントアウトは、コメント化したい範囲を「<!--」と「-->」で囲みます。(同じサーブレットのクラスに対して、web.xmlとアノテーションの両方に設定がある場合は、web.xmlの設定が優先されるため注意してください)
<!--
【この範囲がコメント扱いとなる】
<servlet>
<description></description>
<display-name>SecondServlet</display-name>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>site.knovus.example.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/SecondServlet</url-pattern>
</servlet-mapping>
【この範囲がコメント扱いとなる】
-->
サーバーを起動して、アノテーションで定義したURL(/second)にWebブラウザでアクセスすると、SecondServletが実行されていることがわかります。
http://localhost:8080/WebPractice/second
アノテーションで定義した、もう1つのURL(/2nd)でも、同じSecondServletが実行できていますね。
http://localhost:8080/WebPractice/2nd
いかがでしたでしょうか?今回は最も基本的なサーブレットの作成と、URLとの紐づけ方法についてご紹介しました。次回はサーブレットのdoPostメソッドと、画面で入力した値をサーブレットで利用する方法についてご紹介します。