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?

(調査中)Spring MVC。bodyのgzip解凍されずに文字列化・MDC格納・レスポンス返却したら連携元でエラーになった

Last updated at Posted at 2025-05-28

✅ 現象の整理

項目 内容
連携元 Accept-Encoding: gzip を付けて HTTP リクエスト送信。つまり「gzipでもいいよ」と宣言。
連携先(本来のサーバ) gzip 圧縮されたレスポンスを返し、Content-Encoding: gzip をヘッダーに付ける。OK。
Proxy ヘッダー Content-Encoding: gzip はそのまま残して中身(body)も gzip 圧縮のまま通している。
あなたのアプリ WebClient + reactor-netty を使って受信し、MDC に body を put(この時点で文字化け)。最終的にそのまま連携元に返却するとエラー発生。

❗ 問題点

  • WebClient が自動で gzip 解凍していない(通常は reactor-netty が自動解凍するが、Content-Encoding に応じた処理が一部の構成でスキップされることがある)。
  • 文字化けの原因は gzip 圧縮されたバイナリを文字列として扱ったため
  • MDC に入れた body が読めないのは、gzip 解凍前の生データを String として無理に扱ったため
  • 連携元が gzip を受け入れると言ったのに、gzip のまま返してしまった。ただし、その内容が正しく解凍可能な gzip でなければ連携元側でもエラーになります。

✅ 誰に責任がある?

当事者 判断
連携元 Accept-Encoding: gzip を送るのは HTTP/1.1 標準仕様。責任なし。
連携先 Content-Encoding: gzip を付けて返しているのは正しい。問題なし。
Proxy 通常、gzip 圧縮レスポンスを中継するならそのままにするのが正しい。削除してはいけない。なので問題なし。
あなたのアプリ(中継サービス)
👉 ここで解凍されずに文字列化・MDC格納・レスポンス返却したのが直接的な原因です。

✅ 正しい対処・設計

1. WebClient で受け取ったときに gzip 解凍されているか確認

webClient.get()
    .uri("...")
    .acceptEncoding("gzip")  // 自分からも gzip OK と言っている?
    .retrieve()
    .bodyToMono(byte[].class) // byte配列で受け取る
    .map(bytes -> encodingUtils.autoDecode(bytes, StandardCharsets.UTF_8))

2. MDC に入れる前に文字列化(必要なら解凍)

String decodedBody = encodingUtils.autoDecode(bodyBytes, StandardCharsets.UTF_8);
MDC.put("body", decodedBody);

3. レスポンス返却時には圧縮し直すか、非圧縮で返す

  • 連携元が Accept-Encoding: gzip を指定しているなら gzip で返してもいいが、

    • 中継処理内で一度解凍した場合、再圧縮しないとそのままでは返せない!
  • 逆に、圧縮レスポンスを再構成しないなら Content-Encoding を削除する必要あり。


✅ 最終的な判断

連携元が Accept-Encoding: gzip を送っているのは正しい。問題はあなたのアプリ側で "gzip圧縮されたbodyを文字列として誤って扱った"、"再圧縮せずにそのまま返した" ことにある。


✅ 推奨方針(簡易)

  • WebClient の受信時点で byte[] で受け取り、gzipか確認して手動解凍。
  • MDCやログ、body表示には 文字列化された内容を使う(生バイナリはNG)。
  • 再送信するときは、解凍済みのものを非圧縮で送るか、明示的に再 gzip 圧縮して Content-Encoding: gzip を付けて返す。

0
0
1

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?