【Java & Tomcat】サーブレットのライフサイクル ※サンプルプログラム付き

  • このエントリーをはてなブックマークに追加
  • Pocket

この記事ではサーブレットのライフサイクルについて説明する。

ライフサイクルとは何か

サーブレット(Servlet)のライフサイクル(Servlet Life Cycle)とは、Webコンテナの中でサーブレットが生成されてから消去されるまでの過程である。サーブレットはJavaのクラスがそうであるようにインスタンスが生成され、そのインスタンスが要求されたサービスを実行する。そして、必要なくなったときに削除される。この過程がサーブレットのライフサイクルである。

この図は、サーブレットのライフサイクルを表したものである。

その詳細をはじまりから見てみよう。

はじまり

Javaで書かれたコードがコンパイルされてクラスファイルになる。そして、Webコンテナに配置されたところからサーブレットのライフサイクルが始まる。Webコンテナに配置されたサーブレットは、Webコンテナによってコントロールされる。そして、リクエストがサーブレットに割り当てられた時、Webコンテナは次のステップを実行する。

ステップ1:インスタンスの生成と初期化

もし、サーブレットのインスタンスが存在しなかったなら、Webコンテナは

  1. Servletクラスをロードする。
  2. Servletクラスのインスタンスを生成する。
  3. サーブレットのinit()メソッドを呼び出すことにより、サーブレットのインスタンスを初期化する。

ステップ2:リクエストによるサービスメソッド呼び出し

Webコンテナは、リクエストとレスポンス・オブジェクトを引数として渡すservive()メソッドを起動する。

インスタンスの削除:destroy()メソッド

もしインスタンスを削除することが必要であれば、Webコンテナはdestroy()メソッドを呼び出すことによりサーブレットを終了させる。

ライフサイクルイベント

サーブレットにはライフサイクルイベントを活用する仕組みがあり、サーブレットの状態を知ることができる。ライフサイクルイベントが発生した時、リスナーオブジェクトに呼び出されるメソッドを定義することによって、イベントをモニターしたり、対応した処理をしたりすることができる。

ライフサイクルイベントして活用できる主なものを以下に示す。コンテキストとは、実行情報のことである。

オブジェクト

イベントの詳細

Webコンテキスト

イベント:初期化と消滅。

Webアプリケーションのサーブレットコンテキスト(実行)の変化について通知するためのイベントである。

リスナークラス:javax.servlet.ServletContextListener
イベントクラス:javax.servlet.ServletContextEvent

セッション

イベント:生成、無効、有効、パッシベーション、タイムアウト

Webアプリケーション内のセッションの変化について通知するためのイベントである。

リスナークラス:
javax.servlet.http.HttpSessionListener, javax.servlet.http.HttpSessionActivationListener,

イベントクラス:
javax.servlet.http.HttpSessionEvent

リクエスト

イベント:サーブレトリクエストがWebコンポーネントによって処理されることが始まった。

 

リスナークラス:javax.servlet.ServletRequestListener

イベントクラス:javax.servlet. ServletRequestEvent

どのように活用できるのかを、サンプルプログラムで見てみよう。

ServletContextListenerの仕様

ServletContextListenerクラスにある二つのメソッドのAPI仕様を示す。

contextInitialized(ServletContextEvent sce)

戻り値の型

void

内容

ウェブアプリケーションの初期化のプロセスが始まっている通知である。すべてのサーブレットコンテキストのリスナーは、Webアプリケーションのどんなフィルターもしくはサーブレットでも、初期化される前にコンテキストの初期化を知らされている。

引数:
sce -初期化された サーブレットコンテキストについての情報

contextDestroyed(ServletContextEvent sce)

戻り値の型

void

内容

サーブレットコンテキストがシャットダウンされようとしている通知である。サーブレットコンテキストリスナーがコンテキストの破壊について知らされる前に、すべてのサーブレットとフィルターは破壊されてしまっている。

引数:sce - 破壊されたサーブレットコンテキストについての情報

HttpSessionListenerの仕様

HttpSessionListenerクラスにある二つのメソッドのAPI仕様を示す。

sessionCreated(HttpSessionEvent se)

戻り値の型

void

内容

セッションが生成されたことを通知。

引数:se – 通知イベント。

sessionDestroyed(HttpSessionEvent se)

戻り値の型

void

内容

セッションが無効になることを通知。

引数:se – 通知イベント。

ServletRequestListenerの仕様

ServletRequestListenerクラスにある二つのメソッドのAPI仕様を示す。

sessionCreated(HttpSessionEvent se)

戻り値の型

void

内容

Webアプリケーションのスコープから入ることを通知。

引数:sre – リクエストについての情報。

requestDestroyed(ServletRequestEvent sre)

戻り値の型

void

内容

Webアプリケーションのスコープから出ることを通知。

引数:sre – リクエストについての情報。

 

コンテキストイベントのサンプルプログラム

ライフサイクルイベントを受け取るためには、ListenerクラスにListenerインターフェースを実装することによって定義できる。このサンプルプログラムでは、コンテキストイベントをListenerクラスで受け取っている。その結果はログとして出力される。

このサンプルプログラムを実行させるために、Webサーバーを起動し、しばらく待ってWebサーバーを終了している。この手順で、下記の実行結果が得られる。

実行結果

 

サンプルプログラムの説明

それでは簡単にプログラムの解説をしてゆこう。

  • [1] アノテーションの宣言をする。
  • [2] ServletContextListenerを継承して、ContextEventListenerクラスを提起する。
  • [3] 修飾子publicでメソッドcontextInitialized ()を宣言する。
  • [4] eventオブジェクトからコンテキストを取得する。
  • [5] 「コンテキスト:開始」をコンテキストのログに出力する。
  • [6] 修飾子publicでメソッドcontextDestroyed ()を宣言する。
  • [7] eventオブジェクトからコンテキストを取得する。
  • [8] 「コンテキスト:終了」をコンテキストのログに出力する。

セッションイベントのサンプルプログラム

ライフサイクルイベントを受け取るためには、ListenerクラスにListenerインターフェースを実装することによって定義できる。

実行結果

サンプルプログラムの説明

それでは簡単にプログラムの解説をしてゆこう。

  • [1] アノテーションの宣言をする。
  • [2] HttpSessionListenerを継承して、SessionEventListenerクラスを定義する。
  • [3] 修飾子publicでメソッドsessionCreated ()を宣言する。
  • [4] eventオブジェクトからセッションを取得する。
  • [5] sessionオブジェクトからコンテキストを取得する。
  • [6] 「セッション開始: ID =(セッションIDを取得)」をコンテキストのログに出力する。
  • [7] 修飾子publicでメソッドsessionDestroyed ()を宣言する。
  • [8] eventオブジェクトからリクエストを取得する。
  • [9] eventオブジェクトからコンテキストを取得する。
  • [10] 「セッション終了: ID =(セッションIDを取得)」をコンテキストのログに出力する。

リクエストイベントのサンプルプログラム

ライフサイクルイベントを受け取るためには、ListenerクラスにListenerインターフェースを実装することによって定義できる。

実行結果

サンプルプログラムの説明

それでは簡単にプログラムの解説をしてゆこう。

  • [1] アノテーションの宣言をする。
  • [2] ServletRequestListenerを継承して、RequestEventListenerクラスを定義する。
  • [3] 修飾子publicでメソッドrequestInitialized ()を宣言する。
  • [4] eventオブジェクトからリクエストを取得する。
  • [5] eventオブジェクトからコンテキストを取得する。
  • [6] 「(リクエストを出したクライアントのアドレス)のリクエストがスコープに入る」をコンテキストのログに出力する。
  • [7] 修飾子publicでメソッドrequestDestroyed ()を宣言する。
  • [8] eventオブジェクトからリクエストを取得する。
  • [9] eventオブジェクトからコンテキストを取得する。
  • [10] 「(リクエストを出したクライアントのアドレス)のリクエストがスコープから出る」をコンテキストのログに出力する。

イベント発生させたサーブレットプログラム

ライフサイクルイベントを受け取るためには、ListenerクラスにListenerインターフェースを実装することによって定義できる。

実行結果

手順1)Webサーバーを起動する。

ログ:

手順2)ブラウザにURL: http://localhost:8080/Servlet/EventTest と入力し、Enterを押す。

ブラウザ画面:

ログ:

手順3)ブラウザの更新ボタンを押す。

ブラウザ画面:

ログ:

手順4)Webサーバーを停止する。

ログ:

サンプルプログラムの説明

それでは簡単にプログラムの解説をしてゆこう。

  • [1] アノテーションの宣言をする。
  • [2] HttpServletを継承して、ServleEventTestクラスを定義する。
  • [3] 修飾子publicでメソッドServletException ()を宣言する。
  • [4] 「init()」をコンテキストのログに出力する。
  • [5] 修飾子publicでメソッドdoGet ()をオーバーライドする。
  • [6] HTMLを出力するためのoutオブジェクトを取得する。
  • [7] outオブジェクトに「Event Test Servlet => 」を出力する。
  • [8] セッションsessionオブジェクトを取得する。
  • [9][10] セッションが開始されていない時、セッションを開始する。
  • [11][12] outオブジェクトに「Session has started」を出力し、処理を終了する。
  • [13] outオブジェクトに「Session has closed」を出力する。
  • [14] セッションを終了する。

ライフサイクルの詳細

サーブレットの生成と初期化

@WebServletアノテーションを使ってWebアプリケーションのサーブレット・コンポーネントの定義を行う。このアノテーションはクラスの仕様に含められ、宣言されたサーブレットについての属性情報を含んでいる。アノテーションが付いているサーブレットは少なくともひとつのURLパターンを属性情報として含んでいなければならない。これは、アノテーションのurlPatternsまたはvalue 属性によって特定される。他の全ての属性はオプションで、指定されなければデフォルト設定となる。アノテーションの属性がURLパターンの時だけは、value属性を使用してください。他方、他の属性が使われている時は、urlPatternsを使用してください。

例えば、次のコードの抜粋は、URLパターン「/report」を持つサーブレットを定義する。@WebServletでアノテーションを付加されたクラスはjavax.servlet.http.HttpServletを継承していなければならない。

@WebServlet("/report")public class MoodServlet extends HttpServlet {    ...

Webコンテナは、サーブレットクラスがローディグされ初期化された後、クライアントから送られたリクエストが来る前に初期化しなければならない。永続的な構成データを読むこと、リソースを初期化すること、その他の一度だけのアクティビティを実行することをサーブレットに許可してこのプロセスをカスタマイズするために、サーブレットのinit()メソッドをオーバーライドするか、@WebServletアノテーションのinitParams属性を指定することができる。initParams属性は、@WebInitParamアノテーションを含んでいる。もし初期化プロセスを完了できない時は、サーブレットはUnavailableException例外を発生させる。特定のサーブレットによって必要とされるデータを提供するために初期化パラメータを使用してください。対照的に、コンテキスト属性はWebアプリケーションのすべてのコンポーネントに有効なデータを提供する。

サービスメソッド

サーブレットによって提供されるサービスは、GenericServletのserviceメソッドの中、httpServletオブジェクトのdoMethods(Methodの部分は、Get, Delete, Options, Post, Put, or Trace置き換えられる)の中、またはサーブレットインターフェースを実装したクラスによって定義された他のプロトコルに依存したメソッドの中に実装したものである。serviceメソッドという言葉は、クライアントにサービスを提供するサーブレットクラスの中にあるどんなメソッドのために使われる。

サービス(serviceメソッドのための一般的なパターンは、リクエストから情報を抽出すること、そしてその情報に基づいて外部リソースにアクセスすること、そしてレスポンスに反映させる。HTTPサーブレットのために、レスポンスに反映させるための正しい手順は、次の通りです。

  1. レスポンスから出力ストリームを取り出す。
  2. レスポンスヘッダーに書き込む。
  3. 出力ストリームにすべてのコンテンツ本体を書き込む。

レスポンスがコミットされる前に、レスポンスヘッダーは設定されなければならない。レスポンスがコミットされた後に設定または追加されたどんな試みも、Webコンテナは無視する。

まとめ

この記事では、サーブレットのライフサイクルについて紹介した。サンプルプログラムを実際に動作させるなどして、仕組みを理解しよう。

 

  • このエントリーをはてなブックマークに追加
  • Pocket

このページの続きや関連ページは下記から一覧で確認できる。

短期間でエンジニアになる方法

・「まったくの初心者だけどエンジニアになりたい!」

・「プログラマーとして転職をしたい!」

という方はリナックスアカデミーの資料を見てみてください。短期間で未経験からエンジニアになることができるスクールとして15年間選ばれ続けてきた理由やノウハウが載った資料です。

エンジニアの入り口に立つために必要な勉強技術の最新動向本当に使えるIT資格学習に役立つ国からの奨励金などの情報が詰まっています。

無料で2,3日中にお手元にお届けします。


資料を見てみる

SNSでもご購読できます。

コメントを残す

*

ゼロからエンジニアを目指す方へ
短期間でエンジニアになる方法

必要な勉強や技術の最新動向、本当に使えるIT資格、学習に役立つ国からの奨励金などの情報を無料でお届け

資料を見てみる