我正在使用一个拦截器,我想记录我所做的请求的主体,但我看不到任何这样做的方法。
有可能吗?
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Response response = chain.proceed(request);
long t2 = System.nanoTime();
double time = (t2 - t1) / 1e6d;
if (request.method().equals("GET")) {
Logs.info(String.format("GET " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), response.code(), response.headers(), response.body().charStream()));
} else if (request.method().equals("POST")) {
Logs.info(String.format("POST " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), request.body(), response.code(), response.headers(), response.body().charStream()));
} else if (request.method().equals("PUT")) {
Logs.info(String.format("PUT " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), request.body().toString(), response.code(), response.headers(), response.body().charStream()));
} else if (request.method().equals("DELETE")) {
Logs.info(String.format("DELETE " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITHOUT_BODY, request.url(), time, request.headers(), response.code(), response.headers()));
}
return response;
}
}
结果是:
POST [some url] in 88,7ms
ZoneName: touraine
Source: Android
body: retrofit.client.OkClient$1@1df53f05 <-request.body().toString() gives me this, but I would like the content string
Response: 500
Date: Tue, 24 Feb 2015 10:14:22 GMT
body: [some content]
8条答案
按热度按时间lqfhib0f1#
Nikola的回答对我不起作用,我猜是
ByteString#toString()
的实现发生了变化,这个解决方案对我起作用了:来自
readUtf8()
的文档:从中移除所有字节,将它们解码为UTF-8,然后返回字符串。
这应该是你想要的。
hl0ma9xz2#
我试着从@msung评论正确的答案,但我的声誉不够高。
这是我在把RequestBody变成一个完整的请求之前打印它所做的修改。它工作起来很有魅力。谢谢
ergxz8rk3#
编辑
因为我看到仍然有一些人对这篇文章感兴趣,这里是我的日志拦截器的最终版本(直到下一次改进)。我希望它能保存你们的一些时间。
请注意,此代码使用
OkHttp 2.2.0
(和Retrofit 1.9.0
)wqlqzqxt4#
对于当前版本的OkHttp,您可以使用HTTP Logging Interceptor并将级别设置为
BODY
使用这种方法,您不能为不同的HTTP方法粒度地配置输出,但是它也适用于其他可能具有主体的方法。
以下示例显示了
PATCH
请求的输出(最低限度地编辑):正如您所看到的,这也会打印出标题,正如文档所述,您真的应该小心:
使用
HEADERS
或BODY
级别时,此拦截器生成的日志可能会泄漏敏感信息,如“Authorization”或“Cookie”标头以及请求和响应正文的内容。此数据只能以受控方式或在非生产环境中记录。您可以通过调用
redactHeader()
来编辑可能包含敏感信息的标头。6qqygrtg5#
处理包含或不包含正文的请求的版本:
t5zmwmid6#
Kotlin版本:
jucafojl7#
创建一个单独的新类并实现Intercepter。
获取请求正文
用于查找缓冲区数据是否为UT8格式的扩展
8ftvxx2r8#
我们应该在buffer对象上调用.close()吗?还是使用try-with-resources语句?