質問: is.read(buf)) { os.write(buf, 0, nChunk); } is.close(); } }; return Response .status(Response.Status.OK) .header("Content-Length",file.length()) .header("Content-Disposition", "attachment; filename=\"test.zip\"") .entity(stream) .build(); } } ``` ### 補足情報(言語/FW/ツール等のバージョンなど)
回答: 少し概念的なところから説明します。 Transfer-Encodingヘッダは、HTTP1.0には存在せずHTTP1.1で初めてお目見えしました。 HTTP1.0では、Content-lengthというヘッダでレスポンスデータの全ボディサイズを入れて、レスポンスヘッダにくっつけていました。 Content-lengthにはレスポンスデータのボディデータ全ての合計サイズを入れなければいけなかった為、 レスポンスデータを返却するアプリケーションサーバー側で全て処理を行った後じゃないと応答出来ませんでした(処理後じゃないと全サイズが分からない為)。 しかし、時代が進むにつれて、レスポンスデータサイズが大きくなってきた事から全処理後にレスポンスデータを返す事は、リクエスト受信から応答までの時間が伸びてしまい、現実的じゃなくなってきました。 そこでHTTP1.1規定されたのが、Transfer-Encordingヘッダになります。 Transfer-Encordingヘッダの利点は、"レスポンスデータ全体のパケットサイズは知らんけど、とりあえず今送れるパケットサイズはこれだけです"というサイズ値を付与して、送れるデータサイズ分ずつチャンクという単位で分割して順次送信出来る点です。 この事により、クライアント的には、リクエストを投げた後からすぐに順次レスポンスデータを受け取る事が出来、結果全データの応答時間の短縮を実現しています。 **Content-length:レスポンスデータ全サイズ値が入ったヘッダ。 Transfer-Encodingヘッダ:順次データをチャンクという単位で分割して送ってくる時に使用するヘッダ。 ** 上記の2つは、どちらか一方を使って、レスポンスデータのボディサイズをクライアント側へ返却する事がHTTPプロトコル上決められています。 Content-lengthヘッダが付く場合は、Transfer-Encordingヘッダは付きませんし、そのまた逆もしかりです。片一方だけ付与されます。 現在だと小さいボディサイズを返す場合はContent-lengthに入れて返却、大きなボディサイズを返す場合は、Transfer-Encordingで分割して返却っていうのが私の経験上、見てきた感じだと多いです。 長くなりましたが、ここまでが前置きです。 [クライアント]⇔[WEBサーバー]⇔[APサーバー] という構成の場合、どこでContent-lengthで返すか、Transfer-Encordingで分割して返すかを判断しているかというとAPサーバーになります。 何故なら、レスポンスデータのサイズを知っているのはAPサーバーですから。 Weblogicや、JBossなどのAPサーバーはデプロイされたアプリケーションから渡されたレスポンスデータのボディサイズを見て一定を超えたらTransfer-Encordingヘッダ付けてチャンク分割してレスポンスを返してたはずなので。 なので、作成されようとしているアプリケーション内では特に意識される必要は無いと思いますよ。 (APサーバーが勝手に判断して必要に応じて付けてくれるはずです)