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

Retrofit中如何控制响应体?避免PDF响应解析失败问题

解决Retrofit解析PDF字节流失败的问题

这个问题太常见了——Retrofit默认配置了GSON转换器,它只会乖乖处理JSON格式的数据,碰到PDF这种二进制字节流肯定会“罢工”抛出异常。核心解决思路就是让Retrofit跳过自动反序列化步骤,直接获取原始的响应体,具体操作如下:

1. 修改Retrofit接口的返回类型

把你原来接口里返回的Call<YourCustomModel>(或者其他自定义模型类)改成Call<ResponseBody>,这样Retrofit就不会调用GSON去解析响应内容,而是直接返回原始的响应体对象。

示例代码:

// 原来的接口(会触发GSON解析,导致失败)
// @POST("pdf-download")
// Call<YourModel> fetchPdf(@Body RequestBody request);

// 修改后的接口
@POST("pdf-download")
Call<ResponseBody> fetchPdf(@Body RequestBody request);

如果你的项目用了Kotlin协程,对应的接口可以写成:

@POST("pdf-download")
suspend fun fetchPdf(@Body request: RequestBody): ResponseBody

2. 处理原始响应体获取PDF字节流

在回调(或协程代码块)中,你可以通过ResponseBody的bytes()方法直接获取PDF的原始字节数组,或者用byteStream()获取输入流来处理(适合大文件,避免内存占用过高)。

Java回调示例:

fetchPdfCall.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        if (response.isSuccessful()) {
            ResponseBody body = response.body();
            if (body != null) {
                try {
                    // 获取PDF字节数组
                    byte[] pdfBytes = body.bytes();
                    // 这里可以把字节数组保存为文件,或者传递给PDF查看器
                    savePdfToFile(pdfBytes, "/sdcard/downloads/result.pdf");
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    // 务必关闭ResponseBody,避免资源泄漏
                    body.close();
                }
            }
        } else {
            // 处理请求不成功的情况(比如状态码非2xx)
            Log.e("PDF Fetch", "Request failed with code: " + response.code());
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 处理网络异常等情况
        t.printStackTrace();
    }
});

Kotlin协程示例:

lifecycleScope.launch {
    try {
        val responseBody = fetchPdf(requestBody)
        val pdfBytes = responseBody.bytes()
        // 处理PDF字节
        savePdfToFile(pdfBytes, "/sdcard/downloads/result.pdf")
        responseBody.close()
    } catch (e: IOException) {
        e.printStackTrace()
    } catch (e: Exception) {
        // 处理其他异常
    }
}

关键原理说明

Retrofit会根据你配置的Converter Factory(比如GsonConverterFactory.create())自动反序列化响应体。当接口返回类型是自定义模型时,Retrofit会尝试用GSON把响应内容转成模型对象,但PDF是二进制数据,完全不符合JSON格式,所以必然会抛出解析异常。而ResponseBody是Retrofit的原始响应载体,不会经过任何Converter处理,因此能直接拿到服务器返回的原始字节流。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:47:59