请求修复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的项目,可以通过以下两种方式修复:
- 添加自定义全局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的配置中即可生效。
- 修改OkHttp源码(若有条件)
直接参考OkHttp 4.x的实现逻辑,在RetryAndFollowUpInterceptor.intercept()方法的finally块中添加detachWithViolence()调用,确保异常场景下资源也能被正确释放。
内容的提问来源于stack exchange,提问作者shenqing-code
相关产品推荐
相关产品推荐

