解决Okhttp的Response#body()#string()后Response返回体为空问题

背景及问题

在使用Okhttp时,经常会用到自定义的拦截器,对请求体Request或返回体Response做额外的处理。
在拦截器中,通常使用如下方式获取RequestResponse;

Request request = chain.request();//获取请求
Response response = chain.proceed(request);//处理请求,获取响应体

在处理Response时,通常会对Response中的返回体内容进行日志输出或者是内容判断等。为了获取请求体中的内容通常使用string()函数获取;

		Response response = chain.proceed(request);
        String bodyStr = response.body().string();

在通过string()函数获取返回体中的字符串以后,当我们尝试用同一个Response对象再次使用string()函数获取返回体的内容时,此时获取的内容返回为空字符串。

string()

string()函数被调用后,Response返回体body()中的所有字节都会被移除,其源码如下:

//:ResponseBody.java
    public final String string() throws IOException {
        BufferedSource source = this.source();

        String var3;
        try {
            Charset charset = Util.bomAwareCharset(source, this.charset());
            var3 = source.readString(charset);
        } finally {
            Util.closeQuietly(source);
        }

        return var3;
    }
  //:BufferedSource.java
  /** Removes all bytes from this, decodes them as {@code charset}, and returns the string. */
  String readString(Charset charset) throws IOException;

解决方法

在掉用string()后,使用返回体的String等信息重新创建新的Response对象;

    private Response login(Response response) {
        try {
            Response.Builder builder = response.newBuilder();
            Response clone = builder.build();
            ResponseBody body = clone.body();

            if (body != null) {
                MediaType mediaType = body.contentType();
                if (mediaType != null) {
                    if (isText(mediaType)) {
                        String resp = body.string();
                        XLog.d(resp);//在这里输出请求体内容
                        //创建新的response
                        body = ResponseBody.create(mediaType, resp);
                        //在调用完string()后只有body()的内容清空,所以可以借助newBuilder手动添加body()来新建一个Response对象,对外部而言这两个response是没有区别的
                        return response.newBuilder()
                                .body(body)
                                .build();
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值