在Retrofit2网络请求时打印参数的踩坑记录

发布于 2018-11-11  179 次阅读


常规做法是构造一个拦截器继承自Interceptor

1.先贴代码

先复制一份

@Override
public Response intercept(Chain chain) throws IOException {
    ...
    Request build = builder.build();
    Response response = chain.proceed(build);
    if (Code.DebugState) {
        //打印请求信息
        //先`Copy`一份
        printLog(build, response);
    }
    ...
    return response;
}

打印


private void printLog(final Request request, final Response response) { StringBuilder sb = new StringBuilder(); sb.append("接口描述:").append(Config.Describe); sb.append(" <---> Method:").append(request.method()); sb.append("\nURL:").append(request.url()); sb.append("\n请求参数:"); try { sb.append(bodyToString(request.body())); } catch (IOException e) { sb.append("请求参数解析失败"); } sb.append("\n返回结果:"); try { //踩坑记录:(详见下面) //之前踩坑主要是在这个地方 //要么是请求关闭 //要么是请求重复 ResponseBody responseBody = response.peekBody(1024 * 1024); sb.append(responseBody.string()); } catch (Exception e) { sb.append("返回结果解析失败"); } ULog.commonV(sb.toString()); } private String bodyToString(final RequestBody request) throws IOException { final Buffer buffer = new Buffer(); if (request != null) request.writeTo(buffer); else return ""; return buffer.readUtf8(); }

2.记录(接代码中的注释)

踩坑记录1-请求关闭

这里如果直接使用response.body().string()的方式输出日志,
会因为string()之后,response中的流会被关闭。 因此需要创建一个新的response给应用层处理。
但是处理不慎容易造成请求重复,导致下面2种情况:
1.打印的是旧信息,返回的是新数据
2.返回的是旧信息,打印的是新数据
但是不知道哪里的问题,目前折中处理是打印旧信息,返回新数据

踩坑记录2-请求重复

朋友老叶找到了记录1中问题的原因,给老叶点个赞。
之所以记录1中的问题,请求参数打印正常,返回结果打印却是旧的数据。
是因为之前:request复制了一份,但response却是通过本身的Chain获取的,内存引用没有改变。
response.peekBody()创建的新对象被重复添加到了流里面,这才导致请求2次。


赤夜染尽 千樱散落 零时夜雨 无茵之音