(4)doGet()メソッド――サーブレットの起点
「サーブレットのエントリポイントとなるメソッドです。エントリポイントとは、クラスが呼び出された際に最初に実行されるメソッドのことです。Javaプログラムのエントリポイントはmain()メソッドで、これはJSP/サーブレットコンテナーによって実行されます。で、サーブレットが呼び出されると、次のdoXxxx()のような名前のメソッドが実行されます。どのメソッドが呼び出されるかは『どのHTTPメソッドによって呼び出されたか』によって決まります」
メソッド | 内容 | |
---|---|---|
doGet() | リクエストがHTTP GET(サーバに対してページの取得を要求)メソッドである場合。 | |
doPost() | リクエストがHTTP POST(フォームに入力したデータをサーバに転送する)メソッドである場合。 | |
doPut() | リクエストがHTTP PUT(リソースを更新/作成する)リクエストである場合。 | |
doDelete() | HTTP DELETE(リソースを削除する)リクエストである場合。 | |
doHead() | リクエストがHTTP HEAD(ヘッダのみの情報を要求)リクエストである場合。 | |
doOptions() | リクエストがHTTP OPTIONS(サーバがサポートしているメソッドやオプションを調べる)リクエストである場合。 | |
doTrace() | リクエストがHTTP TRACE(HTTP要求がどのプロキシサーバを経由して送信されるかなど、HTTP の動作をトレースする際に用いられる)リクエストである場合。 | |
「doGet()メソッドは、ブラウザーからGETメソッドでリクエストが来たときに呼ばれるのですね。で、ここではメソッドをオーバーライドして独自の処理を定義しているということですね」
「先にお話ししたように、HttpServletクラスでdoGet()は抽象メソッドとして宣言されています。中身のない空のメソッドですので、ここで具体的な処理を定義しています。このことを『実装』と呼びます」
●パラメーターはrequestとresponse
「パラメーターが2つ設定されてますね」
「ブラウザーからのリクエストとサーブレットから返すレスポンスを操作するためのインスタンスを受け取るためのものです。JSP/サーブレットコンテナーは、doGet()/doPost()メソッドを呼び出す際に、HttpServletRequestインターフェイスとHttpServletResponseインターフェイスのインスタンスを引数として渡してくるので、それぞれをrequestとresponseという2つのパラメーターで受け取るのです」
●インターフェイスはメソッドを呼び出す手段を提供しているだけ
「ちょ、ちょっと待ってください。インターフェイスからはインスタンスを生成できないはずですよ。そもそもインターフェイスには抽象メソッドしかありませんし」
「そうですね、正確には『インターフェイスを実装したクラスのインスタンスが渡される』のです。でも、これらのクラスはJSP/サーブレットコンテナーの内部で定義されていますので、実際のコードを見ることはできません。このような内部的な処理によって生成されるインスタンスを『暗黙オブジェクト』と呼びます」
「何でそんなややこしいことするんですかねぇ」
「まずはそれぞれのインターフェイスで宣言されているメソッドを見てみてください」
「あー、どれもこれもリクエストを処理する際やレスポンスを返す際に使うものばかりですね」
「で、本体部分は別にしてメソッド名だけで呼び出せるようにインターフェイスとして公開しているのです。例えば、HttpServletRequestインターフェイスと、これを実装したJSP/サーブレットコンテナーの内部のクラスの関係は次のようになります」
メソッド | 内容 | |
---|---|---|
getMethod() | リクエストを生成した HTTPメソッドの名前を返す。 | |
getPathInfo() | リクエストしたURLのうちのパス情報を返す。 | |
getServletPath() | リクエストされたURL のうち、サーブレットを呼び出すための部分を返す。 | |
getQueryString() | リクエストされたURLに含まれているクエリ文字列を返す。 | |
getHeader(String name) | リクエストヘッダーの特定のフィールドの値を返す。 | |
getHeaderNames() | リクエストに含まれるすべてのヘッダーフィールド名を列挙型で返す。 | |
getHeaders(String name) | リクエストに含まれるすべてのヘッダーフィールドの値を列挙型で返す。 | |
getDateHeader(String name) | リクエストされた日付データを返す。 | |
getCookies() | Cookieオブジェクトを格納した配列を返す。 | |
getRequested SessionId() |
クライアントのセッションIDを返す。 | |
getRequestURI() | リクエストのURLのうちプロトコル名からクエリ文字列までの部分を返す。 | |
getSession() | リクエストに関連づけられている現在のセッションを返す。 | |
getRemoteUser() | リクエストを生成したユーザが認証されている場合はそのユーザのログイン名を返す。 | |
getAuthType() | Servlet を保護するために使われている認証スキームの名前を返す。 | |
メソッド | 内容 | |
---|---|---|
addCookie(Cookie cookie) | Cookieをレスポンスに追加する。 | |
addDateHeader(String name, long date) | 任意のヘッダーフィールドを追加して日付の値を設定する。 | |
addHeader(String name, String value) | 任意のヘッダーフィールドを追加して任意の文字列を設定する。 | |
addIntHeader(String name, int value) | 任意のヘッダーフィールドを追加して任意の整数値(int)を設定する。 | |
setDateHeader(String name, long date) | 任意のヘッダーフィールドに日付の値をセットしたレスポンスヘッダーを設定する。 | |
setHeader(String name, String value) | 任意のヘッダーフィールドに任意の値をセットしたレスポンスヘッダーを設定する。 | |
void setIntHeader(String name, int value) | 任意のヘッダーフィールドに任意のの整数値(int)をセットしたレスポンスヘッダーを設定する。 | |
setStatus(int sc) | レスポンスのステータスコードを設定する。 | |
encodeURL(String url) | URLがセッションIDを含むようにエンコードする。 | |
sendError(int sc, String msg) | 指定されたステータス番号を使ってエラーレスポンスを送信する。 | |
sendRedirect(String location) | リダイレクト先の URL を指定して、クライアントにリダイレクトレスポンスを送信する。 | |
「このようにすることで、メソッドの利用者はメソッド名だけを書けば呼び出せるというわけです。もちろん、メソッドの中身がどうなっているのかを知る必要もありません。目的に応じて呼び出すだけです」
●ポリモーフィズムの仕組みでメソッド本体を呼び出す
「どうしても腑に落ちないんですが、何でパラメーターの型がインターフェイスなんです?」
「インターフェイスを実装したクラスのインスタンスは、インターフェイス型のパラメーターで受け取ることができます。こうすると、インターフェイスで宣言されているメソッドを『パラメーター.メソッド名()』として呼び出すことができるんです」
「インターフェイスには、メソッドの宣言部しかありませんので、インターフェイスを実装したクラス(ここではサーブレットクラス)でオーバーライドするのが普通ですが、サーブレット側では『インターフェイスを実装したクラス(実装クラス)のインスタンスをインターフェイス型のパラメーターで受け取る』ことをしています。そうすると『インターフェイス型のパラメーターを通じて実装クラスのメソッドを呼び出せる』ようになるのです。いわゆるポリモーフィズムです」
「はぁ、メソッドを呼び出す側は、とにかく何も考えずにインターフェイス型の参照(パラメーター)を使ってメソッドを呼び出せば、本体部分が呼ばれる、そういうわけですね」
●doGet()メソッドの処理はprocessRequest()を呼び出すこと
「話が長くなってしまいましたが、肝心のdoGet()の処理としては、(6)で定義しているprocessRequest()メソッドを呼び出すだけです。引数にはrequest/responseパラメーターを設定しています」
Copyright © ITmedia, Inc. All Rights Reserved.