2.2. Sevletの作成

2.2.1. Servletとは

Servletは、Servletコンテナにより管理される動的コンテンツを生成するJavaテクノロジをベースとしたWebコンポーネントです。他のJavaテクノロジをベースとしたコンポーネントと同様に、Servletはプラットフォームに依存しないJavaクラスです。このJavaクラスは、JavaテクノロジをサポートするWebサーバーにより動的にロードされ実行されるプラットフォーム中間バイトコードです。Servletエンジンとも呼ばれる、Servletコンテナとは、Servlet機能を提供するWebサーバー拡張です。Servletは、Servletコンテナにより実装されるrequest/responseパラダイムを経由するWebクライアントと相互作用します。
つまり、Servletとは、ブラウザによって発せられたリクエストに応答し、レスポンスを組み立てるためのJavaクラスです。

2.2.2. Servletコンテナとは

Servletコンテナは、MIMEベースにデコードしたり、MIMEベースにフォーマットされるリクエストとレスポンスのネットワーク・サービスを提供するWebサーバーまたはアプリケーション・サーバーの一部です。また、Servletコンテナは、Servletのライフサイクルを制御・管理します。
Servletコンテナはホスト・Webサーバーに組み込むことや、そのサーバーのネイティブ拡張APIによってWebサーバーへのアドオン・コンポーネントとしてインストールすることもできます。また、Webが使用可能なアプリケーションサーバーへ組み込むことや、インストールすることも可能です。
すべてのServletコンテナはリクエストとレスポンス用のプロトコルとしてHTTPをサポートしています。また、HTTPS(SSLの上のHTTP)のような追加のリクエスト/レスポンスペースのプロトコルをサポートしている場合もあります。コンテナが実装するHTTPのバージョンはHTTP/1.0およびHTTP/1.1です。コンテナがRFC2616(HTTP/1.1)のキャッシングメカニズムを持つ場合、コンテナはServletにリクエストを配達する前にクライアントからのリクエストを修正したり、あるいはクライアントにレスポンスを送る前にServletによって生成されたレスポンスを修正したり、RFC2616に従い、Servletにそれらを配達せずに、レスポンスを返却することが可能です。
Servletコンテナは、Servletが実行される環境に対してセキュリティ制限を設けることができます。Java 2プラットフォーム、スタンダード・エディションあるいはJava 2プラットフォーム エンタープライズ・エディション環境では、これらの制限がJava 2プラットフォームによって定義されるパーミッション・アーキテクチャを使用して設けられている可能性があります。

2.2.3. Servletのインタフェース

Servletプログラムを作成する上で必要なインタフェースやクラスを説明します。
2.2.3.1. javax.servlet.Servletインタフェース
Servletは直接的、もしくは、間接的にjavax.servlet.Servletインタフェースを実装している必要があります。javax.servlet.Servletインタフェースには、Servletプログラムが必ず実装しなければならないメソッドが定義されています。
2.2.3.2. javax.servlet.GenericServletクラス
javax.servlet.Servletインタフェースを実装したクラスで、プロトコルに依存しないServletを作成する際に使用します。
2.2.3.3. javax.servlet.http.HttpServletクラス
javax.servlet.GenericServletクラスを継承したクラスで、HTTPプロトコルベースのServletプログラムを作成する際に使用します。通常このクラスを継承してServletを作成します。HttpServletクラスは抽象クラスなので、このクラスを継承したServletプログラムは必ず1つのメソッドをオーバライドする必要があります。

2.2.4. Servletのライフサイクル

Servletコンテナは、次のライフサイクルでServletを管理します。
2.2.4.1. ロードとインスタンス化
各ベンダ製品により多少異なりますが、Servletコンテナは、以下のような契機で、Servletをロードしてインスタンス化します。
2.2.4.2. 初期化
Servletに初めてリクエストが行われたとき、Servletコンテナは最初にServletの初期化を行います。その際、Servletコンテナは、 init()メソッドを一度だけ呼び出します。init()メソッドでは、Servletの処理で必要となる、事前の準備に相当する処理などを記述します。具体的には、次のような処理が該当します。
2.2.4.3. リクエストのハンドリング
Servletの初期化が正常に行われた後、Servletコンテナはクライアントからのリクエストをハンドリングします。リクエストは、 ServletRequest型のオブジェクトとして表現されます。レスポンスは、 ServletResponse型のオブジェクトとして表現されます。HTTPプロトコル通信の場合には、 HttpServletRequest型とHttpServletResponse型がServletコンテナにより提供されます。 HttpServletクラスを継承してServletを作成する場合、 HttpServletの次のメソッドをオーバライドします。
表2.2.2.4-1
戻り型
メソッド
説明
protected void
doGet(HttpServletRequest,HttpServletResponse)
リクエストのHTTPメソッドがGETメソッドの場合、Servletコンテナが呼び出すメソッドです。
protected void
doPost(HttpServletRequest, HttpServletResponse)
リクエストのHTTPメソッドがPOSTメソッドの場合、Servletコンテナが呼び出すメソッドです。
protected void
doDelete(HttpServletRequest, HttpServletResponse)
リクエストのHTTPメソッドがDELETEメソッドの場合、Servletコンテナが呼び出すメソッドです。
protected void
doHead(HttpServletRequest,HttpServletResponse)
リクエストのHTTPメソッドがHEADメソッドの場合、Servletコンテナが呼び出すメソッドです。
protected void
doPut(HttpServletRequest,HttpServletResponse)
リクエストのHTTPメソッドがPUTメソッドの場合、Servletコンテナが呼び出すメソッドです。
一般に、doGet()メソッド、もしくは、doPost()メソッドをオーバライドします。
2.2.4.4. その他のサーブレットメソッド
前述のリクエストのハンドリング以外に、Servletのライフサイクルを維持するリソースを管理したい場合に使用されるinitメソッド および destroyメソッド、Servletが自身の情報を提供する目的で使用するgetServletInfoメソッドなどがあります。
表2.2.2.4-2
戻り型
メソッド
説明
public void
init()
Servletコンテナが呼び出すメソッドです。 このServletがサービスを開始できる状態になったことを示します。
public String
getServletInfo()
作者、バージョン、著作権といったServletに関する情報を返します。デフォルトではこのメソッドは空の文字列を返すだけです。 このメソッドをオーバライドして意味のある値が返るようにしてください。
public void
destroy()
Servletコンテナが呼び出すメソッドです。このServlet がサービス提供を停止するときに呼び出されます。
2.2.4.5. サービスの停止
Servletコンテナのリソースが少なくなり、一定時間Servletにアクセスがない場合や、Servletコンテナを終了する場合などに、ServletコンテナはServletのサービスを停止します。その際に destroy()メソッドが呼ばれます。destroy()メソッドでは、終了処理などを記述します。具体的には、次のような処理が該当します。

2.2.5. Servletとスレッド

通常のServletは、複数のユーザからの同時アクセスがある場合、複数のスレッドとして並列処理を行います。このとき、各スレッドは同じServletインスタンスのservice()メソッドに同時にアクセスします。これは、Servletがスレッドセーフにプログラミングされていることを前提とした動作です。つまり、Servletの開発ではスレッドセーフを意識することが重要となります。
この問題の一つの解として、javax.servlet.SingleThreadModelインタフェースの利用があります。これはServletのインスタンスとスレッドが1対1にマッピングされるモデルで、ブラウザからのアクセス数に合わせてServletのインスタンスを複数用意することにより、Servletのインスタンス変数をスレッドセーフとすることができます。しかし、SingleThreadModelインタフェースには、以下のような問題があるため、利用することは望ましくありません。
スレッドセーフなServletプログラミングの考え方は、マルチスレッド環境でのJavaプログラミングと同様です。ポイントとしては、以下のものが挙げられます。
マルチスレッドの問題は開発するアプリケーションの要件により、さまざまなケースが考えられます。スレッドセーフを意識したプログラミング・開発を心がけましょう。

2.2.6. Servletの定義

作成したServletはweb.xmlに定義をします。Servletの定義はweb-app要素の子要素であるservlet要素とservlet-mapping要素で定義します。servlet要素では、ServletのクラスとServletの名前(web.xml内で一意)を定義して、servlet-mapping要素ではservlet要素で定義したServletとURLのマッピングを定義します。以下にServletの定義例を記載します。
<servlet>
  <servlet-name>TestServlet</servlet-name>
  <servlet-class>servlet.TestServlet</servlet-class>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/TestServletUri</url-pattern>
  </servlet-mapping>
</servlet>
この記述例の意味は、servlet.TestServletTestServletという名前で定義して、/TestServletのURLでアクセスされるとTestServletにリクエストを渡すということです。

2.2.7. サーブレットウィザードの活用

サーブレットウィザードでは、Servletを作成して、さらに、Webプロジェクト中のweb.xmlファイルに作成したServletの定義を追加することができます。
メニュー ファイル新規その他 を選択して、新規画面を表示します。


図2.2.2.7-1

新規画面のWeb配下のサーブレットウィザードを選択して、次へ をクリックします。


図2.2.2.7-2

ソース・フォルダーにWebプロジェクトのソース・フォルダーが設定されていることを確認します。
クラス名には、作成するServletのクラス名を入力します。
Java パッケージには、作成するServletが属するパッケージを入力します。
スーパークラスには、初期値でHttpServletクラスが設定されています。
完了 をクリックしてServletクラスを作成します。
次へ をクリックすると、サーブレット・デプロイメント記述子固有情報を入力する画面が表示されます。


図2.2.2.7-3

デプロイメント記述子固有情報入力画面では、 Servletの配備記述を入力します。次の表で入力項目の説明をします。
表2.2.2.7-1
名称
説明
名前
@WebServletアノテーションのname属性の値となります。
または、servlet要素とservlet-mapping要素の子要素であるservlet-name要素の値となります。
説明
@WebServletアノテーションのdescription属性の値となります。
または、servlet要素の子要素であるdescription要素の値となります。
URL マッピング
@WebServletアノテーションのurlPatterns属性の値となります。
または、servlet-mapping要素の子要素であるurl-pattern要素の値となります。
初期化 パラメーター
@WebServletアノテーションのinitParams属性の値となります。
または、servlet要素の子要素であるinit-param要素の定義を編集できます。

Memo
Servlet2.5以下の場合、デプロイメント記述子固有情報がweb.xmlに記入されます。
Servlet3.0以上の場合、デプロイメント記述子固有情報がServletクラスの @WebServletアノテーションに記入されます。

名前URLマッピングは必須項目です。

初期化パラメーターの右端にある追加をクリックすると初期化パラメーターダイアログが表示されます。
名前の入力値が @WebInitParamアノテーションのname属性の値、またはweb.xmlのparam-name要素の値になります。
の入力値が @WebInitParamアノテーションのvalue属性の値、またはweb.xmlのparam-value要素の値になります。
説明の入力値が @WebInitParamアノテーションのdescription属性の値、またはweb.xmlのdescription要素の値になります。


図2.2.2.7-4

次へ をクリックすると、以下の画面が表示されます。


図2.2.2.7-5

この画面では、サーブレットの修飾子、実装するインタフェース、および生成するメソッドのスタブを指定することができます。次の表で入力項目の説明をします。
表2.2.2.7-2
名称
説明
メソッド・スタブの作成
作成するメソッドのスタブクラスを選択します。メソッドの詳細は、
前述のリクエストのハンドリングおよび その他のサーブレットメソッドを参照してください。