Java REST接口返回200状态码但OkHttp客户端响应体为空问题排查
问题根因
响应体为空是几个客户端实现错误共同导致的:
- OkHttpClient配置方式完全错误:OkHttp从3.x版本开始客户端实例为不可变对象,所有网络配置(SSL工厂、主机名校验、超时规则等)必须通过
OkHttpClient.Builder构建时传入,先实例化默认客户端、后续手动调用set方法的写法不会生效,HTTPS连接配置不匹配时会出现能读到状态码但响应体被截断为空的情况。 - SSL协议指定错误:代码中使用过时的
SSL协议,目前主流服务端普遍禁用旧版SSL协议,要求使用TLSv1.2及以上版本,协议不匹配会导致SSL层读取响应内容失败。 - 缺少必要请求头:代码未添加
Accept: application/json请求头,Postman默认会携带通用请求头所以调用正常,服务端使用的JAX-RS框架如果未匹配到对应Accept头,可能返回空响应体。 - 手写重试逻辑不规范:超时重试时未处理连接释放,容易出现连接复用异常,也会导致读空响应。
修正方案
修正客户端构建逻辑
所有配置通过Builder传入,替换SSL协议为TLSv1.2,添加必要请求头,使用OkHttp内置重试机制替换手写重试:
private Response callGETEndpoint(final String url) throws IOException, NoSuchAlgorithmException, KeyManagementException { // 构建信任所有证书的TrustManager(仅测试环境使用,生产环境请替换为正式证书校验逻辑) TrustManager[] trustAllCerts = getTrustManager(); SSLContext sc = SSLContext.getInstance("TLSv1.2"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); // 所有配置通过Builder构建OkHttpClient实例 OkHttpClient okHttpClient = new OkHttpClient.Builder() .sslSocketFactory(sc.getSocketFactory(), (X509TrustManager) trustAllCerts[0]) .hostnameVerifier((hostname, session) -> true) .retryOnConnectionFailure(true) .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build(); // 构建请求时添加Accept头 Request request = new Request.Builder() .url(url) .addHeader("Accept", "application/json") .get() .build(); logger.info(url); return okHttpClient.newCall(request).execute(); }
修正响应读取逻辑
使用try-with-resources自动关闭响应,避免连接泄漏:
try (Response response = client.callGETEndpoint(url)) { if (response != null && response.isSuccessful() && response.code() == 200) { ResponseBody responseBody = response.body(); if (responseBody != null) { String responseString = responseBody.string(); // 此处处理正常响应逻辑 } } }
注意:跳过主机名校验、信任所有证书的写法存在SSL安全风险,仅可用于本地测试环境,生产环境必须配置合规的证书校验规则。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

