Okhttp拦截器问题

Posted

技术标签:

【中文标题】Okhttp拦截器问题【英文标题】:Okhttp Interceptor issue 【发布时间】:2020-09-18 01:41:03 【问题描述】:

我正在尝试向简单的 okhttp (Get) 请求添加标头。如何正确添加 HttpHeader?我可以调试以确保我的 Header 实际发送到服务器吗?

        Request request = new Request.Builder()
                .url("URL")
                .build();

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() 
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException 
                        Request originalRequest = chain.request();
                        Request newRequest = originalRequest.newBuilder()
                                .addHeader("Header", "123")
                                .build();
                        return chain.proceed(newRequest);
                    
                )
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() 
            @Override
            public void onFailure(Call call, IOException e) 
             

我一直在寻找基本的简单示例,但它们使用的是 Retrofit、GSON、Interfaces 或 Kotlin。需要以代码方式理解它。

【问题讨论】:

【参考方案1】:

您可以通过方法 addHeader 发送链作为参数并添加标题。

 Request getRequest = chain.request();
        Request.Builder requestBuilder = getRequest.newBuilder()
            .addHeader("Header", "123");
        Request request = requestBuilder.build();
        return chain.proceed(request);

您也可以访问并查看答案link1 和link2。

这是您可以使用的所有请求结构。

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.addInterceptor(new Interceptor() 
            @Override
            public Response intercept(Interceptor.Chain chain) throws IOException 
                Request original = chain.request();

                Request request = original.newBuilder()
                        .method(original.method(), original.body())
                        .build();

                return chain.proceed(request);
            
        ;
        OkHttpClient client = httpClient.build();

        Request request = new Request.Builder()
                .url("URL")
                .addHeader("Header", "123")
                .build();

        client.newCall(request).enqueue(new Callback() 
            @Override
            public void onFailure(Call call, IOException e) 
                e.printStackTrace();
                Log.d("OKHTTP3", e.getMessage());
                // You get this failure
                runOnUiThread(() -> 

                );
            

            @Override
            public void onResponse(Call call, Response response) throws IOException 
                try 
                    final String _body = response.body().string();
                    Log.d("OKHTTP3", _body);
                    runOnUiThread(() -> 

                    );
                 catch (InterruptedIOException e) 
                    runOnUiThread(() -> 
                        // Or this exception depending when timeout is reached

                    );
                
            
        );

【讨论】:

谢谢,我查看了链接,但它们是不完整的。你能添加包括调用在内的整个代码吗? “return chain.proceed(request);”在哪里返回? @SO80 请查看我编辑的最简单形式的 okhttp 请求调用。 谢谢,但如果没有拦截器,则不会发送标头。 @SO80 请看我编辑的答案现在我添加了拦截器。【参考方案2】:

要检查您的请求并添加标头,您可以使用拦截器。

添加标题,(复制自gist):

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();  
httpClient.addInterceptor(new Interceptor()   
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException 
        Request original = chain.request();

        Request request = original.newBuilder()
            .header("User-Agent", "Your-App-Name")
            .header("Accept", "application/vnd.yourapi.v1.full+json")
            .method(original.method(), original.body())
            .build();

        return chain.proceed(request);
    


OkHttpClient client = httpClient.build();  
Retrofit retrofit = new Retrofit.Builder()  
    .baseUrl(API_BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .client(client)
    .build();

要查看您的标题,您可以使用here提供的示例示例:

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

    long t1 = System.nanoTime();
    logger.info(String.format("Sending request %s on %s%n%s",
        request.url(), chain.connection(), request.headers()));

    Response response = chain.proceed(request);

    long t2 = System.nanoTime();
    logger.info(String.format("Received response for %s in %.1fms%n%s",
        response.request().url(), (t2 - t1) / 1e6d, response.headers()));

    return response;
  

【讨论】:

请将 call 和 onFailure / on Success 添加到第一个代码中,以便我可以使用它【参考方案3】:

使用addHeader() 添加标题。 header() 将已添加的标头名称设置为值。

Request newRequest = originalRequest.newBuilder()
    .addHeader("Header", "123")
    .build();

为了验证它是否正常工作,您可以使用HttpLoggingInterceptor 记录您的网络请求。

【讨论】:

我已经用 .addHeader 更新了我的代码。但没有任何变化。

以上是关于Okhttp拦截器问题的主要内容,如果未能解决你的问题,请参考以下文章

Okhttp 3.x 动态添加/删除验证器/拦截器

OkHttp拦截器的实现原理

多部分中的okhttp登录拦截器

OkHttp3 拦截器源码分析

与 OkHttp 拦截器作斗争

改造:如何从 okhttp 拦截器再次重试请求?