Servlet日記(2000/03/05)

本日の成果

 Servlet API 2.2でうれしい機能の一つに、出力バッファの制御ができるようになったことがあります。今回は、それを実際に試してみます。この程度なら簡単と思ったのですが・・・

 だらだらと長いのですが、次のようなコードを書いてみました。まずバッファサイズを指定して、後は普通通り出力します。その後、reset()メソッドを呼び出して、出力を取り消しています。次に再度出力しますが、今度は途中まで出力したところでflushBuffer()メソッドによりバッファの内容を強制的に送信し、引き続き残りを出力しています。

 で、まず見落としていたことは、reset()メソッドにより出力が取り消されますが、ヘッダで指定したContent-Typeも取り消されます。従って、再度Content-Typeを指定することになりますが、そうすると、getWriter()メソッドも呼び直さないといけないのでしょうか。以下のコードでは、そうしてあります。

 もう一つは、いったんflushBuffer()メソッドを呼ぶとisCommited()メソッドが返す値が真になりますが、さらに残りを出力しても、このメソッドが返す値は真のままです。どういうわけか、このメソッドが返す値はバッファがdirtyかどうかを表すと思いこんでいて、引っかかってしまいました。

 最後にある、コメントになったreset()メソッドを生かすと、例外が発生します。isCommited()メソッドが真を返す条件と、reset()メソッドで例外が発生する条件は、同じなんでしょうね。

public void doGet(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
        PrintWriter out = null;

        res.setBufferSize(128 * 1024);
        res.setContentType("text/html; charset=Shift_JIS");
        out = res.getWriter();

        log("--- part 1 ---");
        log("buffer size = " + res.getBufferSize());
        log("buffer commited = " + res.isCommitted());

        out.println("<html><head><title>送信されないはずのデータ</title></head>");
        out.println("<body>これは送信されないはず</body></html>");
        log("--- part 2 ---");
        log("buffer size = " + res.getBufferSize());
        log("buffer commited = " + res.isCommitted());
        res.reset();
        log("--- part 3 ---");
        log("buffer size = " + res.getBufferSize());
        log("buffer commited = " + res.isCommitted());

        res.setContentType("text/html; charset=Shift_JIS");
        out = res.getWriter();

        out.println("<html><head><title>送信データ</title></head>");
        out.println("<body>ここは送信されたはず");
        log("--- part 4 ---");
        log("buffer size = " + res.getBufferSize());
        log("buffer commited = " + res.isCommitted());
        res.flushBuffer();
        log("--- part 5 ---");
        log("buffer size = " + res.getBufferSize());
        log("buffer commited = " + res.isCommitted());
        out.println("<br>さらに続きがあります</body></html>");
        log("--- part 6 ---");
        log("buffer size = " + res.getBufferSize());
        log("buffer commited = " + res.isCommitted());
        // res.reset(); // これを実行するとIllegalStateExceptionが発生する

        out.close();    
}

本日の教訓

 簡単に見えても油断大敵です。(注意したはずでも、ぬけているんですけど ^^;)

Servlet日記(2000/02/20) Servlet日記の目次 Servlet日記(2000/03/12)