Retrofit 用response.body().string()的方式输出日志注意事项

Retrofit 或者是OkHttp用response.body().string()的方式输出日志注意事项 当我想有时候想打印请求回调数据时,会通过response.body().string()或者responseBody.string()的方式获取json数据字符串。这个就有注意的问题了。 注意事项: 先举个例子:

Log.d("rcjs",response.body().string());
复制代码

Log.d("rcjs",responseBody.string());
复制代码

这个都没问题,但是,

Log.d("rcjs",responseBody.string());
Log.d("rcjs",response.body().string());
复制代码

这样就会GG了。 这是为什么呢? 单独使用这句并不会有问题。 因为,OkHttp不把它存储在内存中,就是你需要的时候就去读一次 只给你了内容,没有给引用,所以一次请求读一次,打印body后原ResponseBody会被清空,response中的流会被关闭,程序会报错,我们需要创建出一个新的ResponseBody 给应用层处理。 原理解析:

 /**
   * Returns the response as a string decoded with the charset of the Content-Type header. If that
   * header is either absent or lacks a charset, this will attempt to decode the response body as
   * UTF-8.
   */
  public final String string() throws IOException {
    return new String(bytes(), charset().name());
  }
复制代码

再往里走

 public final byte[] bytes() throws IOException {
    long contentLength = contentLength();
    if (contentLength > Integer.MAX_VALUE) {
      throw new IOException("Cannot buffer entire body for content length: " + contentLength);
    }

    BufferedSource source = source();
    byte[] bytes;
    try {
      bytes = source.readByteArray();
    } finally {
      Util.closeQuietly(source);
    }
    if (contentLength != -1 && contentLength != bytes.length) {
      throw new IOException("Content-Length and stream length disagree");
    }
    return bytes;
  }
复制代码

可以看出,执行了closeQuietly方法关闭资源操作。

Util.closeQuietly(source);
复制代码

想要打印并能以后继续使用response的解决方法: 1.去新创建一个ResponseBody 去读取,response本身不进行读取操作

ResponseBody responseBody = response.peekBody(1024 * 1024);//关键代码
Log.d("REQUEST_JSON", responseBody.string());
复制代码

这种方式有缺陷,当header的content-length不确定的情况下会出错,所以设置默认大小为1024*1024。 2.通过responseBody,去新建一个Response ,再用Response 其去打印

 ResponseBody responseBody= ResponseBody.create(contentType, bodyString);//先决条件,有responseBody
Response responseNew = response.newBuilder().body(responseBody).build();//关键代码
Log.d("REQUEST_JSON", responseNew.body.string());
复制代码

3.以Buffer的方式去读取显示。

ResponseBody responseBody = response.body();
                    BufferedSource source = responseBody.source();
                    source.request(Long.MAX_VALUE); // Buffer the entire body.
                    Buffer buffer = source.buffer();
                    Charset UTF8 = Charset.forName("UTF-8");
                    Log.d("REQUEST_JSON", buffer.clone().readString(UTF8));
复制代码

以上三种读取打印方式,我倾向后两者。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值