常规做法是构造一个拦截器继承自
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次。