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

Android开发:如何在Retrofit响应中保留errorBody()内容?

这个问题我之前在做Retrofit接口请求的时候踩过坑!核心原因是Retrofit返回的ResponseBody(包括errorBody()拿到的实例)本质是一个一次性的输入流,一旦你调用string()或者byteStream()读取过一次,流就会被关闭,后续再调用就会返回null。

要解决这个问题,关键是提前把errorBody的内容备份到内存里,这样就能在不同场景下多次使用而不依赖原流。这里给你两种实用的方案:

方案1:用Okio备份(推荐,Retrofit自带依赖)

Retrofit底层基于Okio实现,所以不需要额外引入依赖,直接用Okio的source()把整个响应体读取成字节数组,之后就可以随意转换为字符串或者重建ResponseBody:

Kotlin示例:

val errorBody = response.errorBody() ?: return
// 读取所有字节到内存
val errorBytes = errorBody.source().readByteArray()
// 第一次获取错误信息
val errorMsg1 = String(errorBytes, Charsets.UTF_8)
// 其他场景再次获取
val errorMsg2 = String(errorBytes, Charsets.UTF_8)
// 如果需要还能重建一个可复用的ResponseBody
val reusableErrorBody = ResponseBody.create(errorBody.contentType(), errorBytes)

Java示例:

ResponseBody errorBody = response.errorBody();
if (errorBody == null) {
    return;
}
// 读取字节数组
byte[] errorBytes = errorBody.source().readByteArray();
// 多次使用错误信息
String errorMsg1 = new String(errorBytes, StandardCharsets.UTF_8);
String errorMsg2 = new String(errorBytes, StandardCharsets.UTF_8);
// 重建ResponseBody用于后续逻辑
ResponseBody reusableErrorBody = ResponseBody.create(errorBody.contentType(), errorBytes);

方案2:用传统IO流备份

如果不想用Okio,也可以用Java标准的InputStream来读取并备份:

ResponseBody errorBody = response.errorBody();
if (errorBody == null) {
    return;
}
// 用try-with-resources自动关闭流,避免内存泄漏
try (InputStream inputStream = errorBody.byteStream();
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
    byte[] buffer = new byte[1024];
    int readLength;
    while ((readLength = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, readLength);
    }
    // 备份的字节数组
    byte[] errorBytes = outputStream.toByteArray();
    
    // 后续多次使用错误信息
    String errorMsg1 = new String(errorBytes, StandardCharsets.UTF_8);
    String errorMsg2 = new String(errorBytes, StandardCharsets.UTF_8);
} catch (IOException e) {
    e.printStackTrace();
}

注意事项

  • 不要试图直接保存原ResponseBody实例,因为它的流只能读取一次
  • 如果错误响应体特别大,要考虑内存占用,但一般错误信息都是简短的JSON或文本,不会有问题
  • 不管用哪种方案,核心都是把流的内容提前复制到内存(字节数组),这样就能脱离原流多次访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:56:17