第6章 応答 (Response)
responseオブジェクトは、サーバからクライアントへ返すべき総ての情報をカプセル化する。HTTPプロトコルにおいては、この情報は応答メッセージのHTTPヘッダまたはメッセージ本体のどちらかでサーバからクライアントに送り出される。
6.1 バッファリング (Buffering)
効率改善の為、デフォルトとしては要求されてはいないがサーブレットコンテナはクライアントへの出力をバッファリングすることが許されている。以下のメソッドが、ServletResponseインターフェイスを介してバッファリング情報のアクセスと設定の為に用意されている:
- getBufferSize
- setBufferSize
- isCommitted
- reset
- flushBuffer
これらのServletResponseインターフェイスで用意されているメソッドにより、サーブレットがServletOutputStreamとWriterのいずれを使っていようともバッファリング動作が出来る。
getBufferSizeメソッドは、使用中のバッファのサイズを返す。この応答の為にバッファが使われていないときには、このメソッドはint型のゼロ(0)の値を返さねばならない。
サーブレットはsetBufferSizeメソッドを使って応答の為に欲しいバッファのサイズを要求できる。実際に割り当てられるバッファサイズはサーブレットが要求したとおなじサイズにすることは要求されてはいないが、少なくとも要求されたサイズ以上でなければならない。これによりコンテナが固定バッファ長のバッファを再利用して、よければ要求より大きなバッファを用意できる。本メソッドは, ServletOutputStreamあるいはWriterを使ってコンテンツを書き出す前に呼ばねばならない。何らかのコンテンツが既に書きこまれていれば、本メソッドはIllegalStateExceptionをスローする。
メソッドisCommittedは、応答のどのバイトもまだクライアントに送出されていないか否かをブール値で返す。メソッドflushBufferはバッファの中のどの内容をもクライアントあてに送り出す。
メソッドresetは、該応答がcommittedされていない状態である場合にかぎりバッファに存在するデータをクリアする。このreset以前にサーブレットがセットした総てのヘッダとステータスコードも同様にクリアされる。
すでにisCommittedの状態のときにresetメソッドが呼ばれたときは、IllegalStateExceptionがスローされる。このときは、応答とそれに関連する情報に変更は生じない。
使用中のバッファが一杯になったときは、コンテナは直ちにバッファの内容をフラッシュしなければならない。クライアントにデータが送信中であるときの初めての状態のときあは、この応答はこの時点でcommittedであると考えられる。
6.2 ヘッダ (Headers)
サーブレットはHTTP応答のヘッダを以下のHttpSevletResponseインターフェイスのメソッドにより設定できる:
- setHeader
- addHeader
メソッドsetHeaderは、名前と値を与えてヘッダを設定する。すでにヘッダが存在する場合は新しいヘッダに置きかえられる。指定の名前に複数のヘッダ値のセットが存在する場合には、総ての値がクリアされ、新しい値に置きかえられる。
メソッドaddHeaderは、ヘッダの指定した名前と、値のセットにヘッダ値を追加する。与えた名前のヘッダがまだ存在していないときには、本メソッドは新しいセットを作成する。
ヘッダにはintやobject型で表現したほうが良いものもある。HttpServletResponseインターフェイスの以下の便利なメソッドにより、サーブレットは適切なデータ型に対した正しいフォーマットでヘッダをセットすることができる。
- setIntHeader
- setDateHeader
- addIntHeader
- addDateHeader
無事クライアントに送り返される為に、応答がコミットされる前にヘッダが設定されていなければならない。応答がコミットされてしまった後からの如何なるヘッダもサーブレット コンテナは無視する。
6.3 便利なメソッド (Convenience Methods)
HttpServletResponseインターフェイスには、以下のような使い勝手の便を考えたメソッドがある:
- sendRedirect
- sendError
メソッドsendRedirectは、クライアントを異なったURLにリダイレクトするために、しかるべきヘッダとコンテンツ本体をセットする。このメソッドを相対URLで呼ぶことは文法的には誤りではないが、コンテナはこの相対パスを完全に認定されているURLに変換して、クライアントに送り返さねばならない。部分的なURLしか与えられないときで、如何なる理由にしろ、有効なURLに変換できないときは、本メソッドはIllegalArgumentExceptionをスローする。
メソッドsendErrorは、クライアントに返すべきしかるべきヘッダとコンテンツ本体を設定する。オプションとしてのString型のパラメタは、該エラーのコンテンツ本体のものとしてsendErrorメソッドに用意されている。
これらのメソッドは、まだコミットされていないときはこの応答をコミット化の状態にしてしまうとともにこれを終了してしまうという副次的効果がある。これらのメソッドが呼ばれた後は、サーブレットはクライアントにいかなる出力をもしてはならない。これらのメソッドが呼ばれた後の応答への書きこみデータは無視される。
応答バッファにデータが既に書きこまれてはいるがクライアントへはまだ返されたいないとき(言い換えれば応答がコミットされていないときは)、応答バッファのデータはクリアされ、これらのメソッドによるデータで置換えられる。応答がコミットの状態であればこれらのメソッドはIllegalStateExceptionをスローしなければならない。
6.4 国際化 (Internationalization)
特定の言語によるドキュメントの取得をクライアントが要求したり、クライアントが特定の言語を設定したときに対応して、サーブレットは応答の言語属性をクライアントに送り返すことが出来る。この情報はHTTP/1.1仕様書に記された他のメカニズムとともに、Content-Languageヘッダを介して送られる。応答の言語はServletResponseインターフェイスのsetLocateメソッドで設定される。このメソッドで正しくHTTPヘッダを設定されないと、クライアントと正しい言語で通信できない。
一番効果的なのは、ServletResponseインターフェイスのgetWriterメソッドを呼ぶ前にこのメソッドを呼ぶようにプログラミングすることである。これにより、返されたPrintWriterが正しく目的の言語地域用に設定されることが保証される。
メソッドsetLocaleのあとにsetContentTypeメソッドが呼ばれ、与えられたコンテント型にあるcharset要素が存在していれば、コンテント型に指定されたcharsetがsetLocaleメソッドで設定した値をオーバライドする。
6.5 応答オブジェクトのクローズ (Closure of Response Object)
幾つかのイベントが、このサーブレットが要求を満足するコンテンツの総てを用意し、この応答オブジェクトをクローズして良いことを通知する。それらのイベントとは以下のものである:
- サーブレットのserviceメソッドの終了
- setContentLengthで指定された量に応答として書き込まれてしまった
- メソッドsendErrorが呼ばれた
- メソッドsendRedirectが呼ばれた
応答が閉じられると、総てのバッファの内容は、もし残っていれば、直ちにクライアントに向けてフラッシュ(流しだし)されねばならない。