【Java & Tomcat】リクエストのディスパッチ(サンプルプログラム付き)

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

このページでは、サーブレットから他のリソース(サーブレット、JSP、HTMLなど)にリクエストを転送する機能である「ディスパッチ」について紹介する。

リクエストのディスパッチ

Webアプリケーションを作るときに、サーブレットから別のサーブレットへリクエストをフォワード(forward:転送)することや、レスポンスに別のサーブレットの出力をインクルード(include:含める)することはよく使われる技術である。

ディスパッチャー(RequestDispatcher)インターフェイスがこれらの要求を実現している。このインターフェイスを通して、ディスパッチャーがサーブレットからのリクエストをディスパッチ(受け渡し)してくれる。

インクルード

インクルードの処理の流れを見てみよう。クライアントから来たリクエストを最初のサーブレットが受ける。このサーブレットが別のサーブレットを呼び出す。そして、別のサーブレットが処理した後、また処理が最初のサーブレットに戻る。

このサンプルプログラムは、サーブレットServletIncludeクラスがサーブレットServletIncludedにインクルード処理をさせる。

インクルードのコードの書き方は次のようになる。RequestDispatcherオブジェクトを取得して、そのincludeメソッドを呼び出している。

include メソッドAPI仕様

RequestDispatcher クラスのinclude メソッドAPI仕様は次の通りである。

include(ServletRequest request, ServletResponse response)

戻り値の型

void

内容

レスポンスの中にリソース(servlet, JSP page, HTML file) のコンテンツを含ませる。ServletResponseオブジェクトはそのパス要素とパラメータを呼び出し側から変更なしで保持する。

インクルードされたサーブレットは、レスポンスのステータスコードを変更したりやヘッダーに設定したりすることはできない。どんな変更の試みも無視される。

リクエストとレスポンスパラメータは、いずれも呼び出し側のサーブレットのサービスメソッドに渡されたオブジェクトと同じか、ServletRequestWrapperかServletResponseWrapperのサブクラスでなければならない。

 

引数:

request – クライアントのリクエストを含むServletRequetオブジェクト。

response – サーブレットのレスポンスを含むServletResponseオブジェクト。

 

例外:

ServletException – もし、インクルードされたリソースがこの例外を発生させたら。

java.io.IOException - もし、インクルードされたリソースがこの例外を発生させたら。

では、実際のプログラムを見てみよう。

サンプルプログラム

このサーブレットは、インクルード処理を行うサーブレットを途中で起動している。その様子は「start」と「end」の間にIncludedServletの「[[[ IncludedServlet ]]]」という文字列が表示されることから確認できる。

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

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

  • [1] アノテーションの宣言をする。
  • [2] HttpServletを継承して、ServletIncludeクラスを定義する。
  • [3] doGet()メソッドをオーバーライドして定義する。
  • [4] Content Typeにtext/html"を設定する。
  • [5] 文字列をレスポンスへ出力するためのoutオブジェクトを取得する。
  • [6]-[7] outオブジェクトに「Main servlet – start」をHTMLで出力する。
  • [8]-[10] getRequestDispatcherの引数に/ ServletIncludedを指定して、サーブレット処理をインクルードする。
  • [11] outオブジェクトに「Main servlet – end」をHTMLで出力する。
  • [12] </body></html>"をoutオブジェクトに出力して、HTMLを完了させる。

インクルードされるサーブレットのサンプルプログラム

次のサーブレットは、インクルード処理を行う。どんな処理かというと、MainServletが「start」と「end」の文字列を表示する間にIncludedServletが「[[[ IncludedServlet ]]]」という文字列を挟んでクライアントに返信する。

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

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

  • [1] アノテーションの宣言をする。
  • [2] HttpServletを継承して、ServletIncludedクラスを定義する。
  • [3] doGet()メソッドをオーバーライドして定義する。
  • [4] 文字列をレスポンスへ出力するためのoutオブジェクトを取得する。
  • [5] 文字列「[[[ServletIncluded]]]」をoutオブジェクトに出力する。

実行結果

ブラウザにURL:http://localhost:8080/Servlet/ServletIncludeを入力し、Enterを押す。インクルード処理によりstartとendの間に「[[[ IncludedServlet ]]]」がインクルード(含まれる)されている。

表示されるブラウザ画面:

フォワード

フォワードの処理の流れを見てみよう。クライアントから来たリクエストを最初のサーブレットが受ける。このサーブレットが別のサーブレットを呼び出す。そして、別のサーブレットがレスポンスをクライアントに返す。この時、最初のサーブレットはレスポンスバッファーに何か書き込んではいけない。もし、レスポンスバッファーに何か書き込んでいたならば、このメソッドを呼び出す前に書き込んだこのバッファーをクリアしなければならない。

このサンプルプログラムは、サーブレットServletIncludeクラスがサーブレットServletIncludedにインクルード処理をさせる。

フォワードのコードの書き方は次のようになる。RequestDispatcherオブジェクトを取得して、そのforwardメッソッドを呼び出している。

forward メソッドAPI仕様

RequestDispatcher クラスのforwardメソッドAPI仕様は次の通りである。

forward(ServletRequest request, ServletResponse response)

戻り値の型

void

内容

サーブレットからのリクエストをサーバー上の別のリソースへ(servlet, JSP file, or HTML file)転送する。このメソッドはひとつのサーブレットにリクエストの予備処理か、別のリソースにレスポンスを生成することを許す。

getRequestDispatcher()を介して得られるRequestDispatcherのために、ServletRequestオブジェクトは、ターゲットリソースのパスに一致するように調整したパス要素とパラメータを持つ。

forwardはレスポンスがクライアントにコミットされる前に呼び出されるべきである(レスポンスのボディ出力が送信される前)。もし、既にレスポンスがコミットされていたならば、このメソッドはIllegalStateExceptionを発生させる。もしレスポンスバッファーの中にコミットされていない出力があれば、フォワードの前に自動的にクリアされる。

リクエストとレスポンスパラメータは、いずれも呼び出し側のサーブレットのサービスメソッドに渡されたオブジェクトと同じか、ServletRequestWrapperかServletResponseWrapperのサブクラスでなければならない。

 

引数:

request –クライアントがサーブレットに渡すリクエストを表す ServletRequestオブジェクト。

response – サーブレットがクライアントに返すレスポンスを表すServletResponseオブジェクト。

 

例外:

ServletException – もしターゲットのリソースがこの例外を発生させたら。

java.io.IOException – もしターゲットのリソースがこの例外を発生させたら。

java.lang.IllegalStateException – もしレスポンスが既にコミットされていたら。

では、実際のプログラムを見てみよう。

サンプルプログラム

このサーブレットは、別のサーブレットをフォワードする。その様子は、ServletForwardedの出力する文字列が「[[[ServletForwarded]]]」だけであるということから確認できる。

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

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

  • [1] アノテーションの宣言をする。
  • [2] HttpServletを継承して、ServletForwardクラスを定義する。
  • [3] doGet()メソッドをオーバーライドして定義する。
  • [4]-[6] getRequestDispatcherの引数に/ ServletForwardedを指定して、サーブレット処理をフォワードする。

フォワードされるサーブレットのサンプルプログラム

次のサーブレットは、単純に「[[[ IncludedServlet ]]]」という文字列をHTMLでレスポンスに出力する。

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

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

  • [1] アノテーションの宣言をする。
  • [2] HttpServletを継承して、ServletForwardedクラスを定義する。
  • [3] doGet()メソッドをオーバーライドして定義する。
  • [4] Content Typeにtext/html"を設定する。
  • [5] 文字列をレスポンスへ出力するためのoutオブジェクトを取得する。
  • [6]-[8] 文字列「[[[ServletForwarded]]]」をoutオブジェクトにHTMLで出力する。

実行結果

ブラウザにURL:http://localhost:8080/Servlet/ServletForwardを入力し、Enterを押す。フォワードにより「[[[ServletForwarded]]]」だけが表示される。

表示されるブラウザ画面:

リダイレクト

リダイレクトについては、別の記事「リダイレクトの設定(sendRedirect)」を参照のこと。

まとめ

ディスパッチを使う事でクライアント側への最終的な出力結果に複数のサーブレットの処理結果を反映することが出来る。2つ、3つとサーブレットを増やして出力結果を変化させてみよう。

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

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

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

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

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

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

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

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


資料を見てみる

SNSでもご購読できます。

コメントを残す

*

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

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

資料を見てみる