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

OkHttp3请求仅返回响应头无响应体、unexpected end of stream报错求助

解决方案

1. 调整OkHttp配置,解决连接复用兼容问题

你遇到的java.net.ProtocolException: unexpected end of stream异常,核心原因是本地Flask默认的Werkzeug开发服务器的长连接(keep-alive)逻辑和OkHttp默认的连接复用机制不兼容,响应体偏大时服务端会提前断开连接,导致客户端读不到完整响应体。修改OkHttpClient构建代码即可解决:

import okhttp3.ConnectionPool
import java.util.concurrent.TimeUnit

// 省略其他原有代码
val client = OkHttpClient.Builder()
    .addInterceptor(interceptor)
    // 禁用连接池,避免复用已经被服务端断开的连接
    .connectionPool(ConnectionPool(0, 1, TimeUnit.NANOSECONDS))
    // 开启连接失败自动重试
    .retryOnConnectionFailure(true)
    // 适当调高超时阈值,适配大响应体传输
    .readTimeout(30, TimeUnit.SECONDS)
    .writeTimeout(30, TimeUnit.SECONDS)
    .connectTimeout(30, TimeUnit.SECONDS)
    .build()

2. 服务端侧适配方案

Werkzeug是专门用于开发调试的服务器,HTTP处理逻辑的兼容性较差,你可以选择以下任意一种方式修改服务端:

  • 开发阶段可以给所有响应头添加Connection: keep-alive字段,匹配OkHttp的长连接逻辑
  • 直接用Gunicorn、uWSGI等生产级服务器部署Flask服务,部署完成后该问题会直接消失

3. 临时验证方案

如果需要快速验证问题根源,可以强制所有请求关闭长连接,每次请求完成后直接断开连接:
添加统一拦截器给所有请求加头:

val closeConnectionInterceptor = Interceptor { chain ->
    val request = chain.request().newBuilder()
        .header("Connection", "close")
        .build()
    chain.proceed(request)
}

// 把拦截器添加到OkHttpClient的拦截器列表
val client = OkHttpClient.Builder()
    .addInterceptor(interceptor)
    .addInterceptor(closeConnectionInterceptor)
    .build()

可选排查步骤

如果以上方案都未生效,可以先把接口返回类型临时改成Response<String>,先获取原始的响应字符串确认响应本身是完整的,再排查Utilisateur实体类的字段是否和服务端返回完全匹配,避免Gson反序列化异常被误判为流中断问题。

内容的提问来源于stack exchange,提问作者Enima Ben

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:45:03