之前一直被拦截器所困扰,不知道它的作用是什么,今天要封装网络框架必须要封装一个拦截器来处理所以就研究了下 ,可能研究中有点错误但还是记录下来方便以后修改。
首先okhttp很大气的提供了一个日志拦截器来拦截服务器的响应,这个拦截器就是HttpLoggingInterceptor,由于返回的响应的body也就是返回的数据只能访问一次,如果这里打印出来了后面就不能使用了,但是官方也提供了方法打印出来并后面也可以使用,方法如下:
HttpLoggingInterceptor loggingInterceptor =
new HttpLoggingInterceptor((message) -> Logger.i(message));
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(loggingInterceptor);
上边说的是对响应的拦截,还有请求头或者一般的拦截是对发出去的请求的拦截,就相当于把请求拦截下来了,按照自己的意愿组装一下,又发出去了,这样就有一个更好的方式来封装我们请求的公共参数,比如token等,在拦截器里面请求头与参数是通过相同的方式进行添加的,但是底层会对你拦截器添加的参数进行分类封装,如果是请求头就放在请求头里面,如果是一般参数就按照post或get方式封装到响应的地方去,其中封装公共参数或者请求头的方式再或者封装后台与前台约定的参数通过如下的方式进行封装,实现Interceptor的前提下重写intercept()方法
@Override public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Headers.Builder builder = new Headers.Builder();
final AppInfo appInfo = SupportApp.appInfo();
builder.add("Content-Encoding", "gzip")
.add("version-code", appInfo.versionCode)
.add("version-name", appInfo.version)
.add("device", appInfo.deviceId)
.add("platform", "android");
final String channel = appInfo.channel;
if (! TextUtils.isEmpty(channel)) {
builder.add("channel", channel);
}
if (mAccountProvider != null && !Strings.isBlank(mAccountProvider.provideToken())) {
builder.add("Authorization", "Bearer " + mAccountProvider.provideToken());
}
if (!Strings.isBlank(mApiVersionAccept)) {
builder.add("Accept", mApiVersionAccept);
}
Request compressedRequest = originalRequest
.newBuilder()
.headers(builder.build())
.build();
return chain.proceed(compressedRequest);
}
也可以通过下面的方式添加:
OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(chain -> {
Request request = chain.request()
.newBuilder()
.addHeader("App-Key", "bmdehs6pbze6s")
.addHeader("Nonce", "14314")
.addHeader("Timestamp", getTime())
.addHeader("Signature", getSha1("YXUU4EAlfn14314" + getTime()))
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.build();
return chain.proceed(request);
}).build();
其实原理是一样的底层都是实现了 checkNameAndValue(name, value)方法进行添加的
所以封装框架的时候吧公共参数封装到拦截器是一件非常有必要做的事情