Retrofit 是一个很好用的http调用组件。内置的其实也是okhttp。把okhttp封装了一下,让日常的业务交互对http调用的感知变小。
一个http调用只需要一行代码就可以了。具体的Retrofit的用法不在这里阐述。自行百度。
这里只讲解如何让Retrofit能够打印http调用的相关参数日志。开讲:
Retrofit每次调用的时候都会用到OKhttpcilent这个客户端,它默认的client是没有打印日志功能的,查看Retrofit的源码:
public final class Retrofit { public static final class Builder { public Builder client(OkHttpClient client) { return callFactory((okhttp3.Call.Factory)Utils.checkNotNull(client, "client == null")); } public Builder callFactory(okhttp3.Call.Factory factory) { callFactory = (okhttp3.Call.Factory)Utils.checkNotNull(factory, "factory == null"); return this; }
可以看到这里是支持传入自定义的OKhttpclient的,所以我们就构建一个可以打印日志的OKhttpclient传进去,然后让每次Retrofit的调用都可以打印日志。
那么如何构建可以打印日志的OKhttpclient呢?我们来查看OKhttpclient的源码,可以找到如下方法:
public Builder addInterceptor(Interceptor interceptor) { interceptors.add(interceptor); return this; }
这个方法可以给client添加各种各样的拦截器,然后达到自己的一些需求。我们要在这里添加一个日志的拦截器,然后每次client的一些http步骤的调用都会调用这个拦截器来做日志输出。
日志的拦截器需要引入jar包(这个jar包只有一个HttpLoggingInterceptor类。。。搞不懂为什么不直接放到okhttp包里。):
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>logging-interceptor</artifactId> <version>3.1.2</version> </dependency>
然后我们创建一个自己的HttpLoggingInterceptor放到自定义的client中,然后设置到Retrofit中。这样我们的Retrofit就可以打印日志了。具体的实现代码如下:
初始化Retrofit并设置可以打印日志的OKhttpclient:
/** * 调用第三方服务 * * @param baseURL * @param service * @return */ public static <T> T start(String baseURL, Class<T> service) { HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder().addInterceptor(loggingInterceptor).build(); return new Retrofit.Builder().baseUrl(baseURL).client(client).addConverterFactory(GsonConverterFactory.create()).build().create(service); }
这样设置之后我们就可以打印Retrofit的http调用日志了。 代码中有一个 HttpLoggingInterceptor.Level 的枚举。这里是设置要打印的日志的内容的。简单介绍下:
HttpLoggingInterceptor.Level.NONE 不打印,
HttpLoggingInterceptor.Level.BASIC 请求和响应,
HttpLoggingInterceptor.Level.HEADERS 请求和响应+头,
HttpLoggingInterceptor.Level.BODY 请求和响应+头+体,
大家可以根据自己的需要来打印。
这样设置之后再本地启动调试的时候是可以在控制台上看到日志的。但是如果log日志是要输出到日志文件的时候就不好使了。 因为拦截器默认的是输出到控制台。
那么如何解决这个问题?我们来看HttpLoggingInterceptor的源码:
public final class HttpLoggingInterceptor implements Interceptor { public static interface Logger { public abstract void log(String s); public static final Logger DEFAULT = new Logger() { public void log(String message) { Platform.get().log(message); } }; }
这里有个输出日志的接口的实现类, 我们可以实现HttpLoggingInterceptor.Logger接口,然后重写它的log方法,来用自己的log输出工具来输出。这样就可以解决这个问题。具体如何重写。。。
连重写都不会还写什么java代码。。。。