Java Tips:レスポンスとしてバイナリ情報を返すにはJAVA Developer

リクエストに応答したサーブレットが返すレスポンスは、HTMLのような文字データだけでなく、JPEG画像のようなバイナリデータも可能です。このTipsでは例としてJPEGデータを返す方法を紹介します。

» 2004年08月06日 07時41分 公開
[JAVA Developer]

getOutputStreamメソッドを使う

 サーブレットでは,レスポンスとしてHTMLのようなテキストデータを返す場合,javax.servlet.HttpServletResponse#getWriterメソッドを使ってPrinterWriterオブジェクトにテキストデータを書き出すか,対応するJSPにフォワードします。これら対し,レスポンスとしてバイナリデータを書き出す場合は,HttpServletResponse#getOutputStreamメソッドを使ってServletOutputStreamオブジェクトを取得して行います。

 手順としては,HttpServletResponse#setContentTypeメソッドでコンテンツ形式を指定します。パラメータは,MIMEタイプを表す文字列で,JPEGデータであれば"images/hare.jpg"を指定します。バイナリデータの場合,データを書き込む際テキストデータのように文字エンコーディングに対する処理を行わないため,setContentTypeメソッドの呼び出しは,バイナリデータを書き込んだあとでもかまいません。

 バイナリデータの書き出しは,データ型ごとに用意されたServletOutputStream#printおよびprintlnメソッド,writeメソッドを使います。printlnメソッドは,データを書き出したあとに改行文字を書き出します。次のリストは,/images/hare.jpgファイルを読み込み,そのままレスポンスとして返すものです。

リスト1 レスポンスとしてJPEGファイルを返す

public void doGet(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException {
    res.setContentType("image/jpeg");
    ServletOutputStream out = res.getOutputStream();
 
    String realPath = this.getServletContext().
            getRealPath("/images/hare.jpg");
    BufferedInputStream in = new BufferedInputStream(
            new FileInputStream(realPath));
    byte[] data = new byte[1024];
    int len;
    while ((len = in.read(data, 0, 1024)) != -1) {
        out.write(data, 0, len);
    }
    in.close();
}

 データの読み書き部分は,1バイト単位で読み書きすることも可能です。

リスト2 1バイト単位で読み書きする

    int data;
    while ((data = in.read()) != -1) {
        out.write(data);
    }

 この場合でもレスポンスは正しく返るのですが,リスト2はリスト1に比べ読み書き時間がかかります。ファイルサイズが大きくなるほど,その違いは顕著です。このような場合は,1バイト単位の読み書きを行うべきではないでしょう。1回の読み込みサイズに関しては,読み込むバイナリデータのサイズやメモリー容量を十分に考慮して決めましょう。

 「JAVA Developer」より毎週役立つJava Tipsを配信中。ほかにも参考になるTipsは、JAVA Developerサイトのバックナンバーから探すことが可能です。

Copyright(C) 2010 SOFTBANK Creative Inc. All Right Reserved.

注目のテーマ