在使用Retrofit时,如果我们需要打印网络请求的日志(诸如请求地址,参数,耗时,请求返回结果),
一、我可以使用现有的日志库,如下:
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
在使用时,添加如下代码:
//声明日志类
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
//设定日志级别
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//自定义OkHttpClient
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
//添加拦截器
okHttpClient.addInterceptor(httpLoggingInterceptor);
//创建并指定自定义的OkHttpClient
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://ip.taobao.com").addConverterFactory(GsonConverterFactory.create()).client(okHttpClient.build()).build();
//创建接口服务类
TaoBaoApiService taoBaoApiService = retrofit.create(TaoBaoApiService.class);
这样在我们的网络请求中便会有如下日志打印。
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: --> GET http://ip.taobao.com/service/getIpInfo.php?ip=220.248.17.90 http/1.1
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: --> END GET
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: <-- 200 OK http://ip.taobao.com/service/getIpInfo.php?ip=220.248.17.90 (36ms)
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: Server: Tengine
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: Date: Fri, 24 Jun 2016 07:31:03 GMT
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: Content-Type: text/html
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: Transfer-Encoding: chunked
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: Connection: keep-alive
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: Vary: Accept-Encoding
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: X-Powered-By: PHP/5.4.31
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息:
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: {"code":0,"data":{"country":"\u4e2d\u56fd","country_id":"CN","area":"\u534e\u4e1c","area_id":"300000","region":"\u4e0a\u6d77\u5e02","region_id":"310000","city":"\u4e0a\u6d77\u5e02","city_id":"310100","county":"","county_id":"-1","isp":"\u8054\u901a","isp_id":"100026","ip":"220.248.17.90"}}
六月 24, 2016 3:31:04 下午 okhttp3.internal.Platform log
信息: <-- END HTTP (290-byte body)
二、自定义日志打印处理
如果打印的数据不符合要求,我们自定义打印信息的内容和格式
这里我们使用一个自定的,具体代码大致如下:
okHttpClient.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
//获得请求信息,此处如有需要可以添加headers信息
Request request = chain.request();
//添加Cookie信息
request.newBuilder().addHeader("Cookie","aaaa");
//打印请求信息
syso("url:" + request.url());
syso("method:" + request.method());
syso("request-body:" + request.body());
//记录请求耗时
long startNs = System.nanoTime();
okhttp3.Response response;
try {
//发送请求,获得相应,
response = chain.proceed(request);
} catch (Exception e) {
throw e;
}
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
//打印请求耗时
syso("耗时:"+tookMs+"ms");
//使用response获得headers(),可以更新本地Cookie。
syso("headers==========");
Headers headers = response.headers();
syso(headers.toString());
//获得返回的body,注意此处不要使用responseBody.string()获取返回数据,原因在于这个方法会消耗返回结果的数据(buffer)
ResponseBody responseBody = response.body();
//为了不消耗buffer,我们这里使用source先获得buffer对象,然后clone()后使用
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
//获得返回的数据
Buffer buffer = source.buffer();
//使用前clone()下,避免直接消耗
syso("response:" + buffer.clone().readString(Charset.forName("UTF-8")));
return response;
}
});
代码说明已添加注释。需要额外说明一点就是syso函数只是做简单打印,如下:
private static void syso(String msg) {
System.out.println(msg);
}