0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Java]Transfer-Encoding: chunked がある場合に HttpResponse のボディが空になるという問題について

Posted at

背景:Transfer-Encoding: chunked とは?

HTTP で Transfer-Encoding: chunked が使われると、ボディは「チャンク(塊)」に分割されて送られます。この形式では、Content-Length ヘッダーは使われません。

Java の HttpClient はこのチャンク化されたレスポンスを自動で扱うことができますが、処理の書き方によってはボディを正しく読めないことがあります。

確認ポイント(受信側)

1.BodyHandler の指定

HttpClient.send() でレスポンスを受け取る際、以下のようにしてますか?

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

これがない、あるいは BodyHandlers.discarding() を使っていると、ボディは読み込まれません。

2.InputStream で受け取って自前で読む方法

Chunked エンコーディングに問題があると感じた場合は、ofInputStream() で受け取り、自前で確認するのも手です:

HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body(), StandardCharsets.UTF_8))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

これで実際にチャンクが届いているか確認できます。

3. サーバーが Transfer-Encoding: chunked を明示的に設定しているか

HttpServer の実装で Transfer-Encoding: chunked を自分で追加している場合、それが誤ったフォーマットになっている可能性があります。

Java の com.sun.net.httpserver.HttpServer などでは、ボディサイズが不明なときに自動で chunked にしてくれることもあります。ヘッダーを手動でいじる場合は注意が必要です。

確認ポイント(送信側:HttpServer)

HttpExchange を使っていると仮定して、以下のように書くのが一般的です:

exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=UTF-8");
exchange.sendResponseHeaders(200, 0);  // ← 0 を指定すると chunked エンコーディングになる

OutputStream os = exchange.getResponseBody();
os.write("Hello chunked world".getBytes(StandardCharsets.UTF_8));
os.close();

ポイント:

sendResponseHeaders(200, 0):この 0 は「ボディサイズが不明」を意味し、自動で chunked にしてくれる。

自分で Transfer-Encoding: chunked をヘッダーに追加しても、それだけでは機能しません。正しくチャンク形式で送信される必要があります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?