retrofit对请求进行了封装,返回的值也可以进行解析,如果一旦出现错误,难以查找哪里出错了,所以就要用 拦截器进行监听,方便查看数据,更便捷地查找错误
一个正常的retrofit请求
Retrofit retrofit = new Retrofit.Builder().baseUrl(INetWork.URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
INetWork iNetWork = retrofit.create(INetWork.class);
iNetWork.login("zz", "123").enqueue(new Callback<LoginResult>() {
@Override
public void onResponse(Call<LoginResult> call, Response<LoginResult> response) {
Log.i("zzz", "成功");
}
@Override
public void onFailure(Call<LoginResult> call, Throwable t) {
Log.i("zzz", "失败");
}
});
怎么添加一个拦截器呢?
建立一个okhttp对象,放入拦截器
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Log.i("zzz", "request====111111111111111111111111111111");
Log.i("zzz", "request====" + request.headers().toString());
okhttp3.Response proceed = chain.proceed(request);
Log.i("zzz", "proceed====" + proceed.headers().toString());
return proceed;
}
})
.build();
把有拦截器的 okhttp对象放入retrofit
Retrofit retrofit = new Retrofit.Builder().baseUrl(INetWork.URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
INetWork iNetWork = retrofit.create(INetWork.class);
iNetWork.login("zz", "123").enqueue(new Callback<LoginResult>() {
@Override
public void onResponse(Call<LoginResult> call, Response<LoginResult> response) {
Log.i("zzz", "成功");
}
@Override
public void onFailure(Call<LoginResult> call, Throwable t) {
Log.i("zzz", "失败");
}
});
这样在拦截器中就可以读取信息了
注意,拦截器中不可以读取response的body,因为,返回的信息只可以被读取一次,如果读取了。后边就用不到了,所以这里引入新的概念 log拦截器
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.i("aaa", "message====" + message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
log拦截器默认不打印,要设置打印的等级,有4个,body是最大的级别,把她放入okhttp对象中,再把okhttp放入retrofit ,那么就可以打印对应的body,所有的代码
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.i("aaa", "message====" + message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Log.i("zzz", "request====111111111111111111111111111111");
Log.i("zzz", "request====" + request.headers().toString());
okhttp3.Response proceed = chain.proceed(request);
Log.i("zzz", "proceed====" + proceed.headers().toString());
return proceed;
}
})
.addInterceptor(httpLoggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(INetWork.URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
INetWork iNetWork = retrofit.create(INetWork.class);
iNetWork.login("zz", "123").enqueue(new Callback<LoginResult>() {
@Override
public void onResponse(Call<LoginResult> call, Response<LoginResult> response) {
Log.i("zzz", "成功");
}
@Override
public void onFailure(Call<LoginResult> call, Throwable t) {
Log.i("zzz", "失败");
}
});
这里再说一点关于cookie的事,登陆成功后,为了避免回到这个界面每次都要登陆,可以把首次登陆,服务器返回的 请求头 header中的cookie,留下来,然后再次请求可以把她添加进入请求的请求头中,这样就不用再次登陆了,她可以用拦截器实现
package com.oneteam.interceptordemo;
import android.util.Log;
import java.io.IOException;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by dell-pc on 2016/8/31.
*/
public class ECNetWorkUtil {
private static INetWork iNetWork = null;
private ECNetWorkUtil() {
}
/**
* 获得接口实例
*
* @return
*/
public static INetWork getInstance() {
synchronized (Object.class) {
if (iNetWork == null) {
synchronized (Object.class) {
newOneInstance();
}
}
}
return iNetWork;
}
/**
* 创建新实例
*/
public static int n=0;
private static Retrofit retrofit;
private static HashSet<String> cookies = new HashSet<>();
private static OkHttpClient okHttpClient;
private static HttpLoggingInterceptor interceptor;
public static class AddCookiesInterceptor implements Interceptor {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
for (String cookie : cookies) {
builder.addHeader("Cookie", cookie);
Log.v("zzz", "Adding Header: " + cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp
}
Log.v("zzz", "Request Header: " + builder.build().headers().toString());
return chain.proceed(builder.build());
}
}
public static class ReceivedCookiesInterceptor implements Interceptor {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Response originalResponse = chain.proceed(chain.request());
if (!originalResponse.headers("Set-Cookie").isEmpty()) {
for (String header : originalResponse.headers("Set-Cookie")) {
cookies.add(header);
Log.i("zzz","header====="+header);
}
}
Log.v("zzz", "Response Header: " + originalResponse.headers().toString());
return originalResponse;
}
}
private static void newOneInstance() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
// Log.d("zzz", "OkHttp====message " + message);
}
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(new AddCookiesInterceptor())
.addInterceptor(new ReceivedCookiesInterceptor())
.connectTimeout(30, TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(INetWork.URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create()).build();
iNetWork = retrofit.create(INetWork.class);
}
}