OkHttp 拦截器执行顺序:
//执行请求,拿到服务器返回数据。
//Response response = client.getResponseWithInterceptorChain(request);
====getResponseWithInterceptorChain() 【Start】
RealInterceptorChain.proceed()
******当前拦截器序号,index = 0, interceptor: RetryAndFollowUpInterceptor
RetryAndFollowUpInterceptor---- intercept()
RetryAndFollowUpInterceptor: 【1】.RetryAndFollowUpInterceptor processing request
chain.proceed(request)
RealInterceptorChain.proceed()
******当前拦截器序号,index = 1, interceptor: BridgeInterceptor
BridgeInterceptor---- intercept()
BridgeInterceptor: 【2】.BridgeInterceptor adding headers
chain.proceed(request);
RealInterceptorChain.proceed()
******当前拦截器序号,index = 2, interceptor: CacheInterceptor
CacheInterceptor---- intercept()
CacheInterceptor: 【3】.CacheInterceptor checking cache
chain.proceed(request);
RealInterceptorChain.proceed()
******当前拦截器序号,index = 3, interceptor:
【自定义Interceptpr】 ---- intercept()
----Custom interceptor: https://api.example.com/data
chain.proceed(request)
RealInterceptorChain.proceed()
******当前拦截器序号,index = 4, interceptor: ConnectInterceptor
ConnectInterceptor ---- intercept()
ConnectInterceptor: 【4】.ConnectInterceptor establishing connection
chain.proceed(request);
RealInterceptorChain.proceed()
******当前拦截器序号,index = 5, interceptor: CallServerInterceptor
CallServerInterceptor---- intercept()
CallServerInterceptor: 【5】.CallServerInterceptor sending request to server
//......模拟网络请求,拿到服务器返回数据......
// Response response = new Response.Builder().code(200).message("OK").request(request).build();
CallServerInterceptor: 【5】.CallServerInterceptor result:OK
RealInterceptorChain::return interceptor.intercept(next) //index=5
ConnectInterceptor: 【4】 ConnectInterceptor result:OK
RealInterceptorChain::return interceptor.intercept(next) //index=4
【自定义Interceptor】
RealInterceptorChain:: return interceptor.intercept(next) //index=3
----Custom interceptor result: OK
CacheInterceptor: 【3】. CacheInterceptor result:OK
RealInterceptorChain:: return interceptor.intercept(next); //index=2
BridgeInterceptor: 【2】.BridgeInterceptor result:OK
RealInterceptorChain:: return interceptor.intercept(next); //index=1
RetryAndFollowUpInterceptor: 【1】.RetryAndFollowUpInterceptor result:OK
RealInterceptorChain:: return interceptor.intercept(next); //index=0
====getResponseWithInterceptorChain 【End】
//最终拿到服务器返回结果。
Response code: 200 requestUrl: https://api.example.com/data
Response message: OK
Console日志输出:
====interceptors count:6
====getResponseWithInterceptorChain Start
******当前拦截器序号,index = 0, interceptor: RetryAndFollowUpInterceptor
1.RetryAndFollowUpInterceptor processing request
******当前拦截器序号,index = 1, interceptor: BridgeInterceptor
2.BridgeInterceptor adding headers
******当前拦截器序号,index = 2, interceptor: CacheInterceptor
3.CacheInterceptor checking cache
******当前拦截器序号,index = 3, interceptor:
----Custom interceptor: https://api.example.com/data
******当前拦截器序号,index = 4, interceptor: ConnectInterceptor
4.ConnectInterceptor establishing connection
******当前拦截器序号,index = 5, interceptor: CallServerInterceptor
5.CallServerInterceptor sending request to server
5.CallServerInterceptor result:OK
4.ConnectInterceptor result:OK
----Custom interceptor result: OK
3.CacheInterceptor result:OK
2.BridgeInterceptor result:OK
1.RetryAndFollowUpInterceptor result:OK
====getResponseWithInterceptorChain End
Response code: 200 requestUrl: https://api.example.com/data
Response message: OK
HttpClient 模拟okHttp责任链代码实现。
package com.okhttp;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
// 责任链模式在OkHttp中,拦截器的使用示例。
public class HttpClient {
//拦截器列表
private final List<Interceptor> interceptors = new ArrayList<>();
public HttpClient() {
// 添加默认拦截器
interceptors.add(new RetryAndFollowUpInterceptor());
interceptors.add(new BridgeInterceptor());
interceptors.add(new CacheInterceptor());
interceptors.add(new ConnectInterceptor());
interceptors.add(new CallServerInterceptor());
}
//添加自定义拦截器到 ConnectInterceptor 前面。
public HttpClient addInterceptor(Interceptor interceptor) {
interceptors.add(interceptors.size() - 2, interceptor);
return this;
}
public HttpClient addNetworkInterceptor(Interceptor interceptor) {
// 通常网络拦截器添加在 ConnectInterceptor 之前
interceptors.add(interceptors.size() - 2, interceptor);
return this;
}
public Response getResponseWithInterceptorChain(Request request) throws IOException {
System.out.println("====getResponseWithInterceptorChain Start" );
// 3.创建拦截器链,传入index=0
Chain chain = new RealInterceptorChain(interceptors, 0, request);
// 4.启动拦截器链
Response response = chain.proceed(request);
System.out.println("====getResponseWithInterceptorChain End" );
return response; //返回请求服务器的结果
}
// 1.拦截器接口,所有拦截器都要实现这个接口的 intercept 方法。
public interface Interceptor {
Response intercept(Chain chain) throws IOException;
}
// 2.拦截器链接口
public interface Chain {
Request request();
Response proceed(Request request) throws IOException;
}
// 具体的拦截器链实现
private class RealInterceptorChain implements Chain {
private final List<Interceptor> interceptors;
private final int index; //形成拦截器链的关键参数
private final Request request;
public RealInterceptorChain(List<Interceptor> interceptors, int index, Request request) {
this.interceptors = interceptors;
this.index = index;
this.request = request;
}
@Override
public Request request() {
return request;
}
@Override
public Response proceed(Request request) throws IOException {//【关键方法】
if (index >= interceptors.size()) {
throw new AssertionError("No more interceptors to proceed");
}
// 5.创建下一个拦截器 next, 【关键代码,传入index+1】,最终形成链条。
RealInterceptorChain next = new RealInterceptorChain(interceptors, index+1, request);
// 6.从容器中获取当前拦截器,并调用各个拦截器自己的 intercept() 方法
Interceptor interceptor = interceptors.get(index);
System.out.println("******当前拦截器序号,index = " + index
+ ", interceptor: " + interceptor.getClass().getSimpleName());
return interceptor.intercept(next);
}
}
// 示例拦截器实现
private static class RetryAndFollowUpInterceptor implements Interceptor {
// 7.第一个拦截器
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 重试和重定向逻辑
System.out.println("1.RetryAndFollowUpInterceptor processing request");
//【重点代码】:调用下一个拦截器的proceed(),去继续执行,最终形成拦截器链.
Response response = chain.proceed(request);
System.out.println("1.RetryAndFollowUpInterceptor result:" + response.message);
return response;
}
}
private static class BridgeInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 添加必要的请求头
System.out.println("2.BridgeInterceptor adding headers");
Response response = chain.proceed(request);
System.out.println("2.BridgeInterceptor result:" + response.message);
// 处理响应
return response;
}
}
private static class CacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 缓存逻辑
System.out.println("3.CacheInterceptor checking cache");
Response response = chain.proceed(request);
System.out.println("3.CacheInterceptor result:" + response.message);
// 缓存响应
return response;
}
}
private static class ConnectInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 建立连接
System.out.println("4.ConnectInterceptor establishing connection");
Response response = chain.proceed(request);
System.out.println("4.ConnectInterceptor result:" + response.message);
return response;
}
}
// 最后一个拦截器,真正请求网络,得到服务器反馈结果并回传。
private static class CallServerInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 实际发送请求到服务器
System.out.println("5.CallServerInterceptor sending request to server");
// 这里应该是实际的网络请求代码
// 返回模拟响应
Response response = new Response.Builder()
.code(200)
.message("OK")
.request(request)
.build();
System.out.println("5.CallServerInterceptor result:" + response.message);
return response;
}
}
// 请求和响应类(简化版)
public static class Request {
private final String url;
public Request(String url) {
this.url = url;
}
public String url() {
return url;
}
public static class Builder {
private String url;
public Builder url(String url) {
this.url = url;
return this;
}
public Request build() {
return new Request(url);
}
}
}
public static class Response {
private final int code;
private final String message;
private final Request request;
private Response(Builder builder) {
this.code = builder.code;
this.message = builder.message;
this.request = builder.request;
}
public int code() {
return code;
}
public String message() {
return message;
}
public Request request() {
return request;
}
public static class Builder {
private int code;
private String message;
private Request request;
public Builder code(int code) {
this.code = code;
return this;
}
public Builder message(String message) {
this.message = message;
return this;
}
public Builder request(Request request) {
this.request = request;
return this;
}
public Response build() {
return new Response(this);
}
}
}
public static void main(String[] args) {
try {
HttpClient client = new HttpClient();
// 添加自定义拦截器
client.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
System.out.println("----Custom interceptor: " + request.url());
Response response = chain.proceed(request);
System.out.println("----Custom interceptor result: " + response.message);
return response;
}
});
Request request = new Request.Builder()
.url("https://api.example.com/data")
.build();
System.out.println("====interceptors count:" + client.interceptors.size());
//执行请求,拿到服务器返回数据。
Response response = client.getResponseWithInterceptorChain(request);
System.out.println("Response code: " + response.code() + " requestUrl: " + response.request.url);
System.out.println("Response message: " + response.message());
} catch (IOException e) {
e.printStackTrace();
}
}
}
----------End------------------------










网友评论