使用springcloud openfegin 底层使用httpurlconnection 报错too many bytes written executing post

这个错误 “too many bytes written executing POST” 通常发生在使用 java.net.HttpURLConnection 时,当你设置了固定的内容长度(Content-Length),但实际写入到输出流的字节数超过了这个预设的长度。

Spring Cloud OpenFeign 在使用 HttpURLConnection 作为底层客户端时(通过 feign.Client.Default),它会尝试计算请求体的大小,并设置 Content-Length 头部,然后调用 HttpURLConnection.setFixedLengthStreamingMode(int contentLength)。如果后续写入的数据超过了这个 contentLength,就会抛出这个 IOException

以下是可能的原因和排查、解决步骤:

  1. Content-Length 计算不准确:

    • 自定义 Encoder 问题: 如果你使用了自定义的 feign.codec.Encoder,需要确保你的 encode 方法正确地计算了序列化后对象的大小,并将其反映在返回的 RequestTemplatebody() 中,或者确保写入的数据量与 OpenFeign 自动计算的 Content-Length 一致。
    • 数据在序列化后发送前被修改: 某种罕见情况下,如果在 Content-Length 已经根据序列化对象计算得出后,请求体数据又被无意中增加了,可能导致此问题。
  2. 请求体内容问题:

    • 字符编码: 确保客户端和服务器端对请求体的字符编码(如 UTF-8)有统一的理解。如果 String 转换为 byte[] 时使用的编码与计算 Content-Length 时不一致,可能导致字节数不匹配。默认情况下,OpenFeign 的 String 类型请求体会使用 UTF-8。
    • 特殊字符或二进制数据: 如果你发送的是复杂的对象或包含特殊字符、二进制数据,确保你的 Encoder 能够正确处理并计算其字节长度。
  3. HttpURLConnection 的 Bug 或特性:

    • HttpURLConnection 相比 Apache HttpClient 或 OkHttp 来说,功能较少,也更容易出现一些边界情况的问题。

排查和解决步骤:

  1. 启用 Feign 的详细日志:
    在你的 application.ymlapplication.properties 中为你的 Feign 客户端开启 FULL 日志级别,这样可以看到请求头(包括 Content-Length)和请求体。

    logging:
      level:
        # 替换成你的 Feign 客户端接口所在的包名
        com.example.yourpackage.YourFeignClient: DEBUG # 或者 TRACE
    feign:
      client:
        config:
          # default 应用于所有 Feign 客户端,也可以针对特定客户端配置
          default:
            loggerLevel: FULL
    

    观察日志中发送的 Content-Length 值和实际请求体的大小是否匹配。你可以手动计算一下请求体的字节数,看是否与 Content-Length 一致。

  2. 检查你的 Encoder

    • 如果你使用的是默认的 Encoder (如 JacksonEncoder),通常它在计算 JSON 大小时是准确的。
    • 如果你使用了自定义的 Encoder,请仔细检查其逻辑,特别是计算和写入字节流的部分。
  3. 简化请求:
    尝试发送一个非常简单的请求体(比如一个简单的 JSON 对象),看是否还会出现问题。如果简单请求正常,那么问题可能出在复杂请求体的数据或序列化上。

  4. 尝试切换 HTTP 客户端:
    HttpURLConnection 是 OpenFeign 的默认选项之一,但通常不推荐用于生产环境,特别是对于复杂场景或需要更多控制的场景。考虑切换到更健壮的 HTTP 客户端,如 Apache HttpClient 或 OkHttp。
    添加依赖:

    • OkHttp:
      <dependency>
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值