如何将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
相关产品推荐
相关产品推荐

