一、拦截器(Interceptor)

Interceptor 是一个接口,它是在网络请求库中使用的一种机制,用于拦截和处理网络请求和响应。在 Java 中,OkHttp 是一个常见的网络请求库,它也使用 Interceptor 接口来实现这一机制。

Interceptor 接口定义了一个方法 intercept,它接受一个 Chain 对象作为参数,并返回一个 Response 对象。Chain 对象代表请求链中的一个环节,它包含了当前的请求和一系列处理该请求的拦截器。

在 intercept 方法中,你可以执行各种操作,如修改请求头、记录请求日志、添加身份验证信息、修改响应内容等。你可以根据需要自定义拦截器,实现 intercept 方法来处理请求和响应,并将其应用于网络请求中。

通过添加拦截器,你可以在网络请求的发送和接收过程中进行自定义处理,而无需修改每个请求的代码。这使得拦截器成为在网络层级进行请求和响应处理的有力工具,提供了更高的灵活性和可复用性。

二、添加拦截器

2.1、addInterceptor还addNetworkInterceptor?

在选择使用 addInterceptor 还是 addNetworkInterceptor 时,取决于你希望拦截的网络层级。

  • addInterceptor
    方法用于拦截应用层级的请求和响应。这意味着它可以访问应用程序发送的请求和服务器返回的响应,但不能访问底层的网络传输细节。通常情况下,这足以满足大多数的需求,比如添加身份验证、修改请求头等。

  • addNetworkInterceptor
    方法用于拦截网络层级的请求和响应。这意味着它可以访问底层的网络传输细节,包括请求和响应的字节流。它可以用于监视网络流量、修改网络传输行为或进行缓存控制。但要注意,addNetworkInterceptor 方法不会拦截从缓存中提供的响应。

根据你的需求,选择适合的拦截器方法。如果你只需要访问应用层级的请求和响应,一般情况下使用 addInterceptor 就足够了。如果你需要对网络层级进行更深入的控制,可以使用 addNetworkInterceptor。需要注意的是,在使用 addNetworkInterceptor 时,要谨慎处理请求和响应的字节流,以免引起潜在的问题。

2.2、时机

addInterceptor 和 addNetworkInterceptor 方法添加的拦截器在 OkHttp 中的调用时机略有不同:

  • addInterceptor 方法添加的拦截器在应用层级的调用时机是在请求发出后、服务器响应之前。它会被应用于所有的网络请求,包括重定向和重试的请求。在请求链中,每个拦截器的 intercept 方法会按照添加的顺序依次被调用。
  • addNetworkInterceptor 方法添加的拦截器在网络层级的调用时机是在请求发出后、服务器响应之前,并且只会被调用一次。它可以访问到底层的网络传输细节,如请求和响应的字节流。然而,addNetworkInterceptor 方法不会拦截从缓存中提供的响应。

三、自定义拦截器

    override fun intercept(chain: Interceptor.Chain): Response {
        val response = chain.proceed(chain.request())
        return if (response.body() != null && response.body()!!.contentType() != null) {
            val mediaType = response.body()!!.contentType()
            val string = response.body()!!.string()
            val responseBody = ResponseBody.create(mediaType, string)
            val apiResponse = gson.fromJson(string, ApiResponse::class.java)
            //判断逻辑 模拟一下
            

//            if (apiResponse.errorCode == 99999) {
//                //如果是普通的activity话 可以直接跳转,如果是navigation中的fragment,可以发送通知跳转
//                appContext.startActivity(Intent(appContext, TestActivity::class.java).apply {
//                    flags = Intent.FLAG_ACTIVITY_NEW_TASK
//                })
//            }
            response.newBuilder().body(responseBody).build()
        } else {
            response
        }
    }

val string = response.body()!!.string() 只能获取一次

四、所有内置拦截器的介绍

4.1、拦截器责任链

如下是OKHTTP内置的拦截器:

  Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new 

4.2、重试和重定向拦截器 RetryAndFollowUpInterceptor

原理地址:OkHttp3.0(四)-Interceptor拦截器(3)-RetryAndFollowUpInterceptor

Okhttp 内置的第一个拦截器,t 默认支持失败重连,如果想修改可以调用如下方法:

 //设置失败重连  true 允许失败重连,false 不允许失败重连
    public Builder retryOnConnectionFailure(boolean retryOnConnectionFailure) {
      this.retryOnConnectionFailure = retryOnConnectionFailure;
      return this;
    }

4.3、桥接拦截器 BridgeInterceptor

转载:OkHttp源码阅读(五) —— 拦截器之BridgeInterceptor

作用:

  1. 封装request头信息
  2. 处理cookie信息
  3. 处理服务器压缩后的response

核心功能就是将用户请求完全变成一个真正的网络请求,具体字段的含义如下:

字段 含义
Content-Type 定义网络文件的类型和网页的编码,如果未指定 ContentType,默认为[TEXT]/[HTML]
Content-Length 表示的是请求体内容的长度。它和 Transfer-Encoding 是互斥的
Transfer-Encoding 值为 chunked 表示请求体的内容大小是未知的
Host 客户端指定想访问的http服务器的域名/IP和端口号
Connection 默认就是 “Keep-Alive”,就是一个 TCP 连接之后不会关闭,保持连接状态。
Accept-Encoding 优先的内容编码,默认是 “gzip” 告诉服务器客户端支持 gzip 编码的响应
Range 实体的字节范围
Cookie 当请求设置了 Cookie 那么就是添加 Cookie 这个请求头
User-Agent HTTP客户端程序的信息

4.4、缓存拦截器 CacheInterceptor

作用是:缓存网络返回的Response

流程图转载自:Okhttp之CacheInterceptor简单分析在这里插入图片描述

4.5、连接拦截器 ConnectInterceptor

ConnectInterceptor,连接拦截器其实就是为后面的CallServerInterceptor请求服务器拦截器做准备

操作是:

通过Transmitter的newExchange方法创建一个Exchange。
Transmitter是应用和网络之间的一个桥梁,通过transmitter.newExchange构造一个Exchange实例。

ExchangeFinder就是负责连接的创建,把创建好的连接放入连接池,如果连接池中已经有该连接,就直接取出复用。而ExchangeCodec则是对HTTP请求和HTTP响应编码
Exchange则是用来进行发送和接收HTTP request和respone。

4.6、CallServerInterceptor

拦截器链中最后一个拦截器,与服务器的交互如,发出请求和接收响应都是它完成的

参考及转载地址

参考地址:Okhttp拦截器Interceptor学习和使用
参考地址:Interceptor介绍
参考地址:OkHttp3.0(四)-Interceptor拦截器(3)-RetryAndFollowUpInterceptor
参考地址:深入理解OkHttp3 (1):Interceptors

转载和学习地址:Okhttp解析—Interceptor详解
转载和学习地址:Okhttp之CacheInterceptor简单分析

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐