拦截器可以注册为应用拦截器和网络拦截器。
应用拦截器
是在请求执行刚开始,还没有执行OkHttp的核心代码前进行拦截。
通过addInterceptor添加应用拦截器
OkhttpClient client = new OkhttpClient.Builder() .addInterceptor(new LogginInterceptor) .build();
网络拦截器
在连接网络之前进行拦截
addNetworkInterceptor添加网络拦截器。
OkhttpClient client = new OkhttpClient.Builder() .addNetWorkInterceptor(new LogginInterceptor) .build();
两种拦截器特点:
应用拦截器
l 不需要担心是否影响OKHttp的请求策略和请求速度。
l 即使是从缓存中取数据,也会执行Application拦截器。
l 允许重试,即Chain.proceed()可以执行多次。(当然请不要盲目执行多次,需要加入你的逻辑判断)
网络拦截器
l 可以操作像重定向和重试这样的中间响应。
l 对于短路网络的缓存响应不会调用。
l 监视即将要通过网络传输的数据。
l 访问运输请求的Connection。
建议:
如果对拦截器不是很熟的同学,开发过程中,建议使用Application Interception。这样避免对OkHttp请求策略的破坏。
拦截器的重要对象:
Request类
每一个http请求包含URL, request method(GET/POST等等),headers, requestBody.Request通过Request.Builder对象设置各种属性,最终调用build()生成Request对象。
Response类
Response同样是Builder结构包含了responsecode(200, 401等等), headers ,response body。(The responseanswers the request with a code (like 200 for success or 404 for not found),headers, and its own optional body.)
拦截器的使用:
拦截器可以用来做很多东西:
1、 网络请求log打打印
2、 url的判断和再跳转
3、 公共变量的添加(添加token)
4、 返回数据的时候根据code进行数据的分类处理
例子:
网络访问log打印
OkhttpClient client = new OkhttpClient.Builder() .addNetWorkInterceptor(new LogginInterceptor) .build();
url的再跳转
Interceptor appInterceptor = new Interceptor() { public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url(); String s = url.url().toString(); Response response = null; //如果Url中没有包含androidxx关键字,则修改请求链接为http://www.androidxx.cn if (s.contains(“androidxx”)) { request = request.newBuilder().url(“http://www.androidxx.cn”).build(); } response = chain.proceed(request); return response; } };
token的添加:
new OkHttpClient.Builder() .addInterceptor(new Interceptor() { public Response intercept(Chain chain) throws IOException { Request original = chain.request(); String path = original.url().url().getPath(); Request.Builder reqBuilder = original.newBuilder(); if (PathManager.getInstance().isNeedToken(path)) { String token = TokenManager.getInstance().getToken(); if (token != null) reqBuilder.header("Authorization", "Bearer".concat(token)); } Request realRequest = reqBuilder.build(); return chain.proceed(realRequest); } })
数据的预处理:
.addInterceptor(new Interceptor() { public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); String codeStr = String.valueOf(response.code()); if (!codeStr.startsWith(SUCCESS_HEADER)) { WeCommonRep rep; String errorString = response.body().string(); try { rep = new Gson().fromJson(errorString, WeCommonRep.class); } catch (JsonSyntaxException e) { rep = null; } if (rep != null) { if (TextUtils.isEmpty(rep.getMessage())) { throw new APIError("网络请求出错,请稍后重试", response.code()); } else { if (rep.getMessage().equals("Bad credentials")) { // 特别处理 throw new APIError("账户密码错误", response.code()); } else { throw new APIError(rep.getMessage(), response.code()); } } } throw new APIError("网络请求出错,请稍后重试", response.code()); } return response; } })