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

请求修复OkHttp 3.x版本请求体发送异常的BUG

OkHttp 3.x 请求体发送异常BUG分析及修复建议

这个BUG我之前踩过坑,确实会引发非常诡异的请求问题:请求头被当作请求体内容发送,直接导致接口无法正常解析请求数据。

问题现象

当某次请求发送过程中出现异常时,后续发起的请求会错误地复用上一次请求残留的Buffer数据,把原本属于请求头的内容当成自身的请求体发送出去,造成接口接收的数据完全不符合预期。

核心原因:版本间资源释放逻辑的差异

对比OkHttp 3.x和4.x的RetryAndFollowUpInterceptor.intercept()方法实现,就能找到问题根源:

  • OkHttp 4.x:在方法的finally代码块中调用了detachWithViolence()方法,无论请求成功还是失败,都会强制释放请求相关的资源,确保Buffer中的残留数据被清空。
  • OkHttp 3.x:只有在请求正常完成的路径下才会执行资源释放逻辑,一旦发生异常,RetryAndFollowUpInterceptor类第135行的代码根本不会被执行,导致Buffer中未发送的数据被保留下来,被下一个请求错误地消耗。

针对3.x版本的修复方案

如果你还在维护基于OkHttp 3.x的项目,可以通过以下两种方式修复:

  1. 添加自定义全局Interceptor
    在应用层面新增一个Interceptor,在请求完成(无论成功或失败)后手动清理请求体相关的资源,避免数据残留。示例代码如下:
public class ResourceCleanupInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = null;
        try {
            response = chain.proceed(request);
            return response;
        } finally {
            // 尝试清理请求体的Buffer资源
            if (request.body() != null) {
                try {
                    if (request.body() instanceof BufferedRequestBody) {
                        ((BufferedRequestBody) request.body()).buffer().clear();
                    }
                } catch (Exception ignore) {
                    // 忽略清理异常,不影响主请求流程
                }
            }
        }
    }
}

将这个Interceptor添加到OkHttpClient的配置中即可生效。

  1. 修改OkHttp源码(若有条件)
    直接参考OkHttp 4.x的实现逻辑,在RetryAndFollowUpInterceptor.intercept()方法的finally块中添加detachWithViolence()调用,确保异常场景下资源也能被正确释放。

内容的提问来源于stack exchange,提问作者shenqing-code

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:23:02