OKHttp的请求流程

OKHttp的请求流程图:

应用拦截器的实现:

OkHttpClient client = new OkHttpClient().newBuilder()
                .addInterceptor(new LoggingInterceptor()).build();

        class LoggingInterceptor implements Interceptor {
            @Override
            public Response intercept(Interceptor.Chain chain) throws IOException {
                Request request = chain.request();

                Log.d(TAG, "[intercept]test");

                Response response = chain.proceed(request);
                return response;
            }
        }

网络拦截器的实现:

OkHttpClient client = new OkHttpClient().newBuilder()
                .addNetworkInterceptor(new TokenInterceptor()).build();

        class TokenInterceptor implements Interceptor{
            private static final String USER_TOKEN = "Authorization";
            private final String token;

            public TokenInterceptor(String token) {
                this.token = token;
            }
            @Override
            public Response intercept(Chain chain) throws IOException {
                final Request originalRequest = chain.request();
                if(token == null || originalRequest.header("Authorization") != null){
                    return chain.proceed(originalRequest);
                }
                Request request = originalRequest.newBuilder()
                        .header(USER_TOKEN,token)
                        .build();
                return chain.proceed(request);
            }
        }

网络拦截器和应用拦截器的区别主要有以下几点:

应用拦截器:

  1. 不需要担心中间过程的响应,如重定向和重试。
  2. 总是只调用一次,即使HTTP响应是从缓存中获取。
  3. 观察应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match。
  4. 允许短路而不调用 Chain.proceed(),即中止调用。
  5. 允许重试,使 Chain.proceed()调用多次。

网络拦截器:

  1. 能够操作中间过程的响应,如重定向和重试。
  2. 当网络短路而返回缓存响应时不被调用。
  3. 只观察在网络上传输的数据。
  4. 携带请求来访问连接。

关闭Socket

进程A与进程B通过Socket通信,假定进程A输出数据,进程B读入数据。进程A如何告诉进程B所有数据已经输出完毕呢?有几种处理办法:

  1. 当进程A与进程B交换的是字符流,并且都一行一行地读/写数据时,可以事先约定以一个特殊的标志作为结束标志,例如以字符串“bye”作为结束标志。当进程A向进程B发送一行字符串“bye”,进程B读到这一行数据后,就停止读数据。

  2. 进程A先发送一个消息,告诉进程B所发送的正文长度,然后再发送正文。进程B先获知进程A将发送的正文长度,接下来只要读取完该长度的字符或字节,就停止读数据。

  3. 进程A发完所有数据后,关闭Socket或关闭Socket的输出流。当进程B读入了进程A发送的所有数据后,如果再次执行输入流的read()方法时,该方法返回-1;如果执行BufferedReader的readLine()方法,那么该方法返回null;如果执行DataInputStream的readXXX()方法,那么将会抛出EOFException异常。进程B可以以此为依据判断已经到达了输入流的末尾。

OKhttp http1.x 与 http2.0 区别
HTTP2.0的前世

文章目录
|