通过定义拦截器 Interceptor ,可以在发送请求或接受请求响应时对数据进行预处理和判断。在开发阶段,为了调试方便,通常在请求的时候,可以直接通过 Log 打印出请求的一些信息,而对于 Header ,Token 的统一管理添加,也可以通过 Interceptor 来实现。
HelloWorld
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import okhttp3.*; import java.io.IOException; public class MyInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request().newBuilder() .addHeader("Content-Type", "application/json") .build(); Headers headers = request.headers(); System.out.println("Content-Type is : " + headers.get("Content-Type")); String requestUrl = request.url().toString(); String methodStr = request.method(); RequestBody body = request.body(); String bodyStr = (body==null?"":body.toString()); Response response = chain.proceed(request); if (response != null) { System.out.println("Response is not null"); } else { System.out.println("Response is null"); } return response; } }
|
上面的代码定义了一个 Interceptor ,对 request 请求添加了一个请求头 Content-Type ,值是 application/json,使用了该 Interceptor 的 client 发起的所有请求,都会自动添加上这个请求头。
request 的几个重要方法:
- url : 获取请求地址
- method : 获取请求方式
- body : 获取请求体
使用 Interceptor
1 2 3
| OkHttpClient client = new OkHttpClient().newBuilder() .addInterceptor(new MyInterceptor()) .build();
|
TokenInterceptor
拦截器的作用在于处理请求信息,对请求数据加密或者在请求响应时存储 cookies ,或者封装 access token 便于服务器验证等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Interceptor mTokenInterceptor = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); if (Your.sToken == null || hasAuthorizationHeader(originalRequest)) { return chain.proceed(originalRequest); } Request authorised = originalRequest.newBuilder() .header("Authorization", Your.sToken) .build(); return chain.proceed(authorised); } };
|
如果 token 是空的,比如对于登录请求,是没有 token 的,只有等到登陆之后才有 token,这时候就不需要添加 token。另外,如果请求中已经带有验证 header 了,比如你手动设置了一个另外的 token,那么也不需要再为请求添加这一个 token。
Authenticator
如果需要在遇到 401 Not Authorised 的时候进行刷新 token,可以使用 Authenticator,这是一个专门设计用于当验证出现错误的时候,进行询问获取处理的拦截器:
1 2 3 4 5 6 7 8 9
| Authenticator mAuthenticator = new Authenticator() { @Override public Request authenticate(Route route, Response response) throws IOException { String sToken = service.refreshToken(); return response.request().newBuilder() .addHeader("Authorization", sToken) .build(); } }
|
分别使用 OkHttpClient.Builder 对象的 addNetworkInterceptor(…) 和 authenticator(…) 添加定义好的拦截器。
Cookies
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class CookiesInterceptor implements Interceptor { private Context context; public CookiesInterceptor(Context context) { this.context = context; } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Request compressedRequest = request.newBuilder() .header("cookie", getCookies(context)) .build(); Response response = chain.proceed(compressedRequest); saveCookies(response.headers(), context); return response; } }
|
上面定义的 CookiesInterceptor 当请求成功之后,使用 saveCookies 方法保存服务器返回的 cookies 信息,在请求之前,读取本地缓存好的 cookie 信息添加到 header 中。
配置 HttpClient
1 2 3 4 5 6 7 8 9
| OkHttpClient client = ...; client.networkInterceptors() .add(new CookiesInterceptor(context)); File cacheDirectory = new File(context.getCacheDir() .getAbsolutePath(), "HttpCache"); Cache cache = new Cache(cacheDirectory, 20 * 1024 * 1024); client.setCache(cache);
|