web-dev-qa-db-ja.com

サーブレットの出力ストリームをフラッシュする必要がありますか?

HttpServletResponseからOutputStreamを「フラッシュ」する必要がありますか?

私はすでに サーブレット出力ストリームを閉じる必要がありますか? それを閉じる必要がないことを確認しましたが、フラッシュする必要があるかどうかは明確ではありません。コンテナにも期待できますか?

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
   throws ServletException, IOException {
   byte[] response = getResponse();
   String responseType = getResponseType();

   response.setContentLength(response.length);
   response.setContentType(responseType);
   response.getOutputStream().write(response);
   response.getOutputStream().flush(); // yes/no/why?
}
31
Carlos Aguayo

する必要はありません。 servletcontainerがフラッシュして閉じます。ところで、クローズはすでに暗黙的にフラッシュを呼び出しています。

Servlet 3.1仕様の5.6章も参照してください

5.6応答オブジェクトのクローズ

応答が閉じられると、コンテナーは応答バッファー内の残りのすべてのコンテンツをすぐにクライアントにフラッシュする必要があります。次のイベントは、サーブレットが要求を満たし、応答オブジェクトが閉じられることを示しています。

  • サーブレットのserviceメソッドの終了。
  • 応答のsetContentLengthまたはsetContentLengthLongメソッドで指定されたコンテンツの量がゼロより大きく、応答に書き込まれました。
  • sendErrorメソッドが呼び出されます。
  • sendRedirectメソッドが呼び出されます。
  • completeAsyncContextメソッドが呼び出されます。

サーブレットのサービスを実行している間にflushを呼び出すことは、通常、同じストリームに複数のライターがあり、ライター(バイナリ/文字データが混在するファイルなど)を切り替えたい場合、またはストリームポインターを開いたままにしたい場合にのみ有益です。不確かな時間(ログファイルなど)。

47
BalusC

他の質問で得たのと同じ答えがここに当てはまると思います。それがストリームの場合は、フラッシュして閉じます。それ以外の場合は、特に明記されていない限り、ストリーム作成者が行う必要があります。

3
mdrg

「フラッシュする必要はありません」というルールの陰湿な例外を指摘するには、IBM WebSphere Application Serverを操作し、応答Writerを使用します(OutputStreamではなく)。私はそれを洗い流さなければなりませんでした。そうしないと、私の応答データの最後の部分が失われました。 IBMのHttpServletResponseクラスは実際にはOutputStreamをフラッシュしますが、Writerには別のバッファーを使用し、それをフラッシュしないと思います。他のアプリケーションサーバーがこれを行うようです。

したがって、応答データをWriterに送信する場合は、フラッシュする方が安全です。ただし、OutputStreamをバーゲンにフラッシュする必要はありません。

(私はこれをコメントとして投稿したでしょうが、それを行う評判はありませんでした。)

2
Renardo