AnotherHelloWorldにおける文字変換とバイトバッファの使い方

 


 以下にAnotherHelloWorldサーブレットの、performTaskメソッドのプログラムの内容を説明する。

 

このメソッドでは、応答出力用に4つのオブジェクトが使われている。これを下図に示す。

-      OutputStream型のosは応答オブジェクトのバイト出力のためのストリームである。テキスト出力用のPrintWriterを使わないのは、このバッファの出力をエンジンが目的の文字セットに変換してしまい、正確なサイズが得られないからである(注:JSPの場合は、JspWriterにはgetBufferSizegetRemainingのメソッドが用意されている)。

-      バイト形式のデータを蓄積し、そのサイズを知るために、ByteArrayOutputStream型のbytesを生成する。ここでは1,024バイトのバッファを用意したが、これを超える入力があった場合は、自動的に拡大される。このクラスにはsizeというメソッドがあり、蓄積されているデータのバイトサイズを知ることができる。

-      Javaが使っているunicodeの文字列を、指定された文字コードに変換してバイト列とするために、送るべきストリームと文字エンコーディングをパラメタとしてOutputStreamWriter型のoswを生成する。このバッファのサイズは8,192バイトであり、これを超える入力があった場合は自動的に出力ストリームに吐き出される。サポートされていない文字コードを指定すると、UnsupportedEncodingExceptionを生じる。このプログラムでは、サーブレットが使った実際のエンコーディングをシステムコンソールに書き出しているが、デバッグ終了時にはこの行をコメントアウトする。このクラスのwriteメソッドを呼び出すごとに文字コンバータを呼び出している。

-      writeメソッドを呼ぶ度に文字コンバータが呼ばれるのは効率的でないので、このオブジェクトは通常BufferedWriterで包む。このプログラムでもoutなるオブジェクトを生成している。コンストラクタでサイズを指定しないとデフォルトの8,192バイトのバッファが用意される。バッファ容量を越える入力があった場合には、これまでのデータを、自分が包んでいるWriterに吐き出す。メソッドflushは、今まで蓄積されている内容を吐き出すとともに、包んでいるWriterflushもコールする。即ちflushは伝播するので、最初のWriterflushをかけるだけでよい。flushout -> osw -> bytesと伝わるが、bytesではこのメソッドは何も生じない。bytesに蓄積されたバイトデータはwrteToメソッドを使ってosに渡される。

 

これらの4つの出力用オブジェクトが理解されれば、プログラムの各行の説明は不要であろう。しいて説明するなら、

-      文字変換はout.flush();で一括oswが行う。

-      Content-Lengthヘッダ行はresponse.setContentLength(bytes.size());の行でなされる。

 

このプログラムには確認のためにシステムコンソールに出力している個所があるが、皆さんがこれを実際に応用される場合には、コメントアウトしなければならない。AnotherHelloWorldは、HTTP/1.0クライアントへのキープアライブ応答やまたファイルなどのバイナリデータの応答に応用できるので、良く理解されることをお勧めする。

 

 

前節     目次     次節