[Chain Demo Code] 模拟 OkHttp 中 Interceptor 的工作原理 #Java #Pattern
interceptor1: request -> Hello
interceptor2: request -> [Hello]
---------------- Real Call ----------------
interceptor2: response -> [Hello]'s response
interceptor1: response -> {[Hello]'s response}
Request Success: {[Hello]'s response}import java.util.ArrayList;
import java.util.List;
/**
* Created by twiceYuan on 2017/7/20.
*/
public class RequestManager {
public static void main(String args[]) {
// 打印日志拦截器1
MockServer.addInterceptor(chain -> {
Request request = chain.request();
System.out.println("interceptor1: request -> " + request.body);
Response response = chain.proceed(request);
System.out.println("interceptor1: response -> " + response.body);
return response;
});
// Interceptor1 : 在请求体前后添加 []
MockServer.addInterceptor(chain -> {
Request request = new Request("[" + chain.request().body + "]");
return chain.proceed(request);
});
// Interceptor2 : 在响应体前后添加 {}
MockServer.addInterceptor(chain -> {
Response response = chain.proceed(chain.request());
return new Response("{" + response.body + "}");
});
// 打印日志拦截器2
MockServer.addInterceptor(chain -> {
Request request = chain.request();
System.out.println("interceptor2: request -> " + request.body);
Response response = chain.proceed(request);
System.out.println("interceptor2: response -> " + response.body);
return response;
});
Response response = MockServer.request(new Request("Hello"));
System.out.println("\nRequest Success: " + response.body);
}
static class MockServer {
static List<Interceptor> mInterceptors = new ArrayList<>();
static Response request(Request request) {
return request(request, mInterceptors);
}
static Response request(Request request, List<Interceptor> interceptors) {
if (interceptors.size() == 0) {
return realCall(request);
} else {
Interceptor interceptor = interceptors.get(0);
// 只要存在拦截器,就构造一个责任链
return interceptor.call(new Chain() {
@Override
public Request request() {
// 每个链中的请求都回调同一个对象,这样每次针对于请求做操作都是操作在同一个对象上
// 然后拦截器通过使用 proceed 传入处理后的请求,讲请求对象传给下一链
return request;
}
@Override
public Response proceed(Request request) {
// 传递给下一链时,从当前拦截器列表中删除当前拦截器
List<Interceptor> newInterceptors = new ArrayList<>(interceptors);
newInterceptors.remove(interceptor);
return MockServer.request(request, newInterceptors);
}
});
}
}
private static Response realCall(Request request) {
System.out.println("---------------- Real Call ----------------");
return new Response(request.body + "'s response");
}
static void addInterceptor(Interceptor interceptor) {
mInterceptors.add(interceptor);
}
}
interface Interceptor {
Response call(Chain chain);
}
interface Chain {
Request request();
Response proceed(Request request);
}
static class Request {
String body;
Request(String body) {
this.body = body;
}
}
static class Response {
String body;
Response(String body) {
this.body = body;
}
}
}
import java.util.ArrayList;
import java.util.List;
/**
* Created by twiceYuan on 2017/7/20.
* 参考 Python Decorator 重写后的版本
*/
public class PyRequestManager {
public static void main(String args[]) {
// 原始请求日志
MockServer.addInterceptor(chain -> request -> {
System.out.println("interceptor1: request -> " + request.body);
Response response = chain.proceed(request);
System.out.println("interceptor1: response -> " + response.body);
return response;
});
// Interceptor1 : 在参数体前后添加 []
MockServer.addInterceptor(chain -> request -> {
Request newRequest = new Request("[" + request.body + "]");
return chain.proceed(newRequest);
});
// Interceptor2 : 在响应体前后添加 {}
MockServer.addInterceptor(chain -> request -> {
Response response = chain.proceed(request);
return new Response("{" + response.body + "}");
});
// 最终请求日志
MockServer.addInterceptor(chain -> request -> {
System.out.println("interceptor2: request -> " + request.body);
Response response = chain.proceed(request);
System.out.println("interceptor2: response -> " + response.body);
return response;
});
Response response = MockServer.request(new Request("Hello"));
System.out.println("\nRequest Success: " + response.body);
}
static class MockServer {
static List<Interceptor> mInterceptors = new ArrayList<>();
static Response request(Request request) {
return request(request, mInterceptors);
}
static Response request(Request request, List<Interceptor> interceptors) {
Chain chain = realCall();
for (Interceptor interceptor : interceptors) {
chain = interceptor.call(chain);
}
return chain.proceed(request);
}
private static Chain realCall() {
return request -> {
System.out.println("---------------- Real Call ----------------");
return new Response(request.body + "'s response");
};
}
static void addInterceptor(Interceptor interceptor) {
mInterceptors.add(interceptor);
}
}
interface Interceptor {
Chain call(Chain chain);
}
interface Chain {
Response proceed(Request request);
}
static class Request {
String body;
Request(String body) {
this.body = body;
}
}
static class Response {
String body;
Response(String body) {
this.body = body;
}
}
}