Spring Boot使用Feign发起REST调用时出现too many bytes written异常求助
解决Feign调用时
too many bytes written异常的方案 问题根源
这个异常本质是Feign默认使用的HttpURLConnection在处理请求体时,存在Content-Length声明值与实际写入字节数不匹配的冲突:Feign提前计算并设置了Content-Length,但HttpURLConnection在流式写入时,实际发送的字节数和声明值不一致,触发了IO异常。直接移除Content-Length会导致服务端无法正确解析请求体,进而返回400错误。
可行解决方案
1. 替换Feign默认客户端为OkHttp
OkHttp对请求体和Content-Length的处理更健壮,能避免这类底层传输问题。
- 添加依赖:
Maven:
Gradle:<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> <version>你的Feign版本(比如11.8)</version> </dependency>implementation 'io.github.openfeign:feign-okhttp:11.8' - 启用OkHttp客户端:
在application.yml/application.properties中添加配置:feign: okhttp: enabled: true
2. 自定义Feign拦截器,正确处理Content-Length
不要直接移除Content-Length,而是确保Feign使用正确的计算逻辑:
- 编写请求拦截器,清除可能错误的Content-Length设置,让Feign编码器自动计算准确值:
import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Component; @Component public class FeignContentLengthInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 移除手动设置的Content-Length,交由Feign自动计算 template.headers().remove("Content-Length"); // 统一请求体编码为UTF-8,避免编码差异导致字节数计算偏差 template.header("Content-Type", "application/json;charset=UTF-8"); } }
3. 检查请求体序列化配置
序列化后的字节数与计算的Content-Length不匹配,也会触发该异常:
确保Feign使用的序列化工具(如Jackson)和服务端配置一致:
- 统一字符编码为UTF-8
- 禁用可能导致序列化结果不一致的特性(如
WRITE_DATES_AS_TIMESTAMPS) - 检查自定义序列化器是否存在字节数计算偏差
示例:配置统一编码的Jackson Feign编码器:
import com.fasterxml.jackson.databind.ObjectMapper; import feign.codec.Encoder; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.nio.charset.StandardCharsets; @Configuration public class FeignEncoderConfig { @Bean public Encoder feignEncoder(ObjectMapper objectMapper) { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(objectMapper); converter.setDefaultCharset(StandardCharsets.UTF_8); return new SpringEncoder(() -> converter); } }
内容的提问来源于stack exchange,提问作者TesUser476797
相关产品推荐
相关产品推荐

