You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重复Transfer-Encoding响应头引发客户端异常,求Spring Boot场景解决方案

分块编码响应损坏问题:重复Transfer-Encoding头导致客户端IOException

问题场景

  • 存在三个Spring Boot服务:Client、Proxy、API,Client通过Proxy转发请求调用API
  • 约1%的响应出现损坏,客户端抛出异常:java.io.IOException: Illegal character in chunk size: 123

错误原因分析

  • 该异常表明响应采用分块编码(chunked),但缺失块大小标识,直接以JSON对象的起始符{(十六进制值为123)开头
  • 客户端收到Transfer-Encoding: chunked响应头,要求按分块规则读取响应,但因缺少块大小信息,无法解析响应从而抛出异常

排查过程

  • 检查Proxy转发后的API响应头,发现存在重复的Transfer-Encoding头
  • API端逻辑:当返回动态内容(如来自数据库的数据)时,Spring/Tomcat无法预先确定内容长度,会自动启用分块编码并添加Transfer-Encoding头
  • Proxy端问题:Proxy的头转换代码中,okttp3Headers.names()是集合类型,不会产生重复头,但Proxy内部的Tomcat会额外添加一次Transfer-Encoding头,疑似Tomcat bug;升级Spring Boot/Tomcat至最新版本后问题仍未解决
  • 复现条件:仅在负载场景下可复现,例如300次请求中约出现3-4次错误
  • 临时方案:在API端手动移除Transfer-Encoding头(此时会自动添加Content-Length头)可解决问题,但该方案并非合理的长期解决方案

Proxy相关代码片段

Proxy使用OkHttpClient实现请求转发,以下是处理请求并转换响应头的代码:

...        
return new ResponseEntity<>(
        responseBodyString,
        convertHeaders(forwarderRequestResponse.headers()),
        Objects.requireNonNull(HttpStatus.resolve(forwarderRequestResponse.code())));
}

public HttpHeaders convertHeaders(Headers okttp3Headers) {
    var headers = new HttpHeaders();
    for (String headerName : okttp3Headers.names()) {
        for (String headerValue : okttp3Headers.values(headerName)) {
            headers.add(headerName, headerValue);
        }
    }
    return headers;
} 

求助

请分享相关问题处理经验或提供合理的解决方案。


内容的提问来源于stack exchange,提问作者Ilja Veselov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:27:17