okhttp 请求拦截器和响应拦截器

在做处理网络请求的时候,可以直观的看到每次请求的传参和响应是非常有帮助的。

 public static API get() {
        if (api == null) {
            synchronized (Retrofit.class) {
                if (api == null) {

                    OkHttpClient httpClient = new OkHttpClient
                            .Builder()
                            .addInterceptor(new RequestLoggerInterceptor())
                            .addInterceptor(new ResponseLogInterCeptor())
                            .build();
                    Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(API.BASE_URL)
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(httpClient)
                            .build();

                    api = retrofit.create(API.class);
                }
            }
        }
        return api;
    }
复制代码

请求的拦截器非常简单

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

            Log.d(TAG, "url     =  : " + request.url());
            Log.d(TAG, "method  =  : " + request.method());
            Log.d(TAG, "headers =  : " + request.headers());
            Log.d(TAG, "body    =  : " + request.body());

            return chain.proceed(request);
        }
    }
复制代码

而响应的拦截器需要考虑body()只能被调用一次的问题,开始的时候我单纯的以为这样就可以

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


            Log.d(TAG, "code     =  : " + response.code());
            Log.d(TAG, "message  =  : " + response.message());
            Log.d(TAG, "protocol =  : " + response.protocol());
            Log.d(TAG, "string   =  : " + response.body().string());


            Response clone = response.newBuilder().build();
            return clone;
        }
    }
复制代码

开始以为这样就是clone了一个Response对象,后来发现太年轻了

  public Builder newBuilder() {
    return new Builder(this);
  }


Builder(Response response) {
      this.request = response.request;
      this.protocol = response.protocol;
      this.code = response.code;
      this.message = response.message;
      this.handshake = response.handshake;
      this.headers = response.headers.newBuilder();
      this.body = response.body;
      this.networkResponse = response.networkResponse;
      this.cacheResponse = response.cacheResponse;
      this.priorResponse = response.priorResponse;
      this.sentRequestAtMillis = response.sentRequestAtMillis;
      this.receivedResponseAtMillis = response.receivedResponseAtMillis;
    }

   public Response build() {
      if (request == null) throw new IllegalStateException("request == null");
      if (protocol == null) throw new IllegalStateException("protocol == null");
      if (code < 0) throw new IllegalStateException("code < 0: " + code);
      if (message == null) throw new IllegalStateException("message == null");
      return new Response(this);
    }

复制代码

同一个body嘛。

稍微改一下

static class ResponseLogInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());

            Log.d(TAG, "code     =  : " + response.code());
            Log.d(TAG, "message  =  : " + response.message());
            Log.d(TAG, "protocol =  : " + response.protocol());

            if (response.body() != null && response.body().contentType() != null) {
                MediaType mediaType = response.body().contentType();
                String string = response.body().string();
                Log.d(TAG, "mediaType =  :  " + mediaType.toString());
                Log.d(TAG, "string    =  : " + string);
                ResponseBody responseBody = ResponseBody.create(mediaType, string);
                return response.newBuilder().body(responseBody).build();
            } else {
                return response;
            }
        }
    }
复制代码

关键在于response.newBuilder().body(responseBody).build(); 这里传入了一个新构建的body。这样才能保证在后续操作中调用body.string()不会抛出异常。

当然在输入body().string()的时候,还要做MediaType的类型判断

转载于:https://juejin.im/post/5a31ee4c6fb9a045204c3bb1

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值