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

如何将OkHttp3的Gzip流响应转换为JSON?附代码片段

嗨,我来帮你搞定把OkHttp3的Gzip流响应转换成JSON的问题!下面是具体的解决方案,结合你的代码场景来梳理:

OkHttp3 Gzip响应转JSON的实现方案

一、优先用OkHttp自动解码(最简单省心)

OkHttp默认就支持自动处理带有Content-Encoding: gzip头的压缩响应,不需要手动写解压缩逻辑,只要你没刻意禁用这个功能就行。

检查OkHttpClient配置

确保你的OkHttpClient没有移除默认的GzipInterceptor:

// 默认OkHttpClient已经内置Gzip解码逻辑,无需额外配置
OkHttpClient client = new OkHttpClient.Builder()
    // 别加 removeInterceptor(GzipInterceptor.class) 这类禁用代码
    .build();

修改你的getData方法

直接读取响应体字符串,再用JSON库(比如Gson,从你的TypeToken来看应该用的是Gson)解析成目标对象:

private <T> T getData(String url, PostModel postModel, TypeToken<T> typeToken) throws ApiException, IOException, ConnectionException {
    Response response = new CallApi<T>(Connection.getOfficeApiUrl()).post(url, postModel);
    
    // 先判断响应是否成功
    if (!response.isSuccessful()) {
        throw new IOException("请求失败,响应码:" + response.code());
    }
    
    // OkHttp已经自动完成Gzip解压缩,直接拿字符串
    String jsonContent = response.body().string();
    
    // 用Gson解析为目标类型
    Gson gson = new Gson();
    return gson.fromJson(jsonContent, typeToken.getType());
}

二、手动处理Gzip流(自动解码失效时用)

如果遇到响应头没正确标记Content-Encoding但实际是Gzip压缩的情况,就需要手动解压缩流:

private <T> T getData(String url, PostModel postModel, TypeToken<T> typeToken) throws ApiException, IOException, ConnectionException {
    Response response = new CallApi<T>(Connection.getOfficeApiUrl()).post(url, postModel);
    
    if (!response.isSuccessful()) {
        throw new IOException("请求失败,响应码:" + response.code());
    }
    
    // 手动解压缩流的核心逻辑
    try (InputStream rawStream = response.body().byteStream();
         GzipInputStream gzipStream = new GzipInputStream(rawStream);
         BufferedReader reader = new BufferedReader(new InputStreamReader(gzipStream, StandardCharsets.UTF_8))) {
        
        StringBuilder jsonBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            jsonBuilder.append(line);
        }
        
        // 解析为目标对象
        Gson gson = new Gson();
        return gson.fromJson(jsonBuilder.toString(), typeToken.getType());
    }
}

三、关键注意事项

  • 响应体只能被消费一次:不管是response.body().string()还是byteStream(),调用后就不能再重复调用,否则会报错。
  • 资源关闭:手动处理流时,一定要用try-with-resources语法自动关闭流,避免资源泄漏。
  • 如果你的CallApi封装了响应处理,要确保它没有提前消费掉响应体,否则你拿不到原始流来处理。

内容的提问来源于stack exchange,提问作者Ahmad Aghazadeh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:47:53