美文网首页
okhttp 请求拦截器和响应拦截器

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

作者: pdog18 | 来源:发表于2017-07-05 09:36 被阅读2054次

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

     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的类型判断

    相关文章

      网友评论

          本文标题:okhttp 请求拦截器和响应拦截器

          本文链接:https://www.haomeiwen.com/subject/qulvcxtx.html