twiceyuan
7/23/2017 - 9:28 AM

[Chain Demo Code] 模拟 OkHttp 中 Interceptor 的工作原理 #Java #Pattern

[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;
        }
    }
}