Bagaimana cara menambahkan header ke pencegat permintaan OkHttp?

95

Saya memiliki pencegat ini yang saya tambahkan ke klien OkHttp saya:

public class RequestTokenInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
  Request request = chain.request();
  // Here where we'll try to refresh token.
  // with an retrofit call
  // After we succeed we'll proceed our request
  Response response = chain.proceed(request);
  return response;
}
}

Bagaimana cara menambahkan header untuk meminta di pencegat saya?

Saya mencoba ini tetapi saya membuat kesalahan dan saya kehilangan permintaan saya saat membuat permintaan baru:

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

        try {
            Log.d("addHeader", "Before");
            String token = TokenProvider.getInstance(mContext).getToken();
            newRequest = request.newBuilder()
                    .addHeader(HeadersContract.HEADER_AUTHONRIZATION, O_AUTH_AUTHENTICATION + token)
                    .addHeader(HeadersContract.HEADER_CLIENT_ID, CLIENT_ID)
                    .build();
        } catch (Exception e) {
            Log.d("addHeader", "Error");
            e.printStackTrace();
            return chain.proceed(request);
        }

        Log.d("addHeader", "after");
        return chain.proceed(newRequest);
    }
}

Perhatikan bahwa, saya tahu saya dapat menambahkan header saat membuat permintaan seperti ini:

Request request = new Request.Builder()
    .url("https://api.github.com/repos/square/okhttp/issues")
    .header("User-Agent", "OkHttp Headers.java")
    .addHeader("Accept", "application/json; q=0.5")
    .addHeader("Accept", "application/vnd.github.v3+json")
    .build();

Tapi itu tidak sesuai dengan kebutuhan saya. Saya membutuhkannya di pencegat.

Morteza Rastgoo
sumber
1
Pencegat Anda terlihat benar. Apa yang tidak berhasil?
Jesse Wilson

Jawaban:

153

Akhirnya, saya menambahkan header dengan cara ini:

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

        newRequest = request.newBuilder()
                .addHeader(HeadersContract.HEADER_AUTHONRIZATION, O_AUTH_AUTHENTICATION)
                .addHeader(HeadersContract.HEADER_X_CLIENT_ID, CLIENT_ID)
                .build();
        return chain.proceed(newRequest);
    }
Morteza Rastgoo
sumber
1
untuk beberapa alasan ini tidak menambahkan tajuk ke permintaan saya ?! Saya menggunakan okHttp.Builder dan networkInterceptors (). Add (interceptor) dengan kode yang sama seperti dalam jawaban ini, tetapi header tidak ditambahkan.
Informatic0re
bagaimana cara menambahkan header untuk permintaan youtube? Apakah itu packageName dan kunci API Anda dan kemudian melewati.addheader(params1, params2);
RoCk RoCk
@RoCk Anda dapat memiliki RestClients terpisah yang memiliki konfigurasi header berbeda.
Morteza Rastgoo
27

Anda bisa melakukannya dengan cara ini

private String GET(String url, Map<String, String> header) throws IOException {
        Headers headerbuild = Headers.of(header);
        Request request = new Request.Builder().url(url).headers(headerbuild).
                        build();

        Response response = client.newCall(request).execute();
        return response.body().string();
    }
gaurang
sumber
5
Ini bukan pencegat.
bekce
15

berikut adalah inti berguna dari lfmingo

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();
chebaby
sumber
10

Menghadapi masalah serupa dengan sampel lain, kelas Kotlin ini berhasil untuk saya

import okhttp3.Interceptor
import okhttp3.Response

class CustomInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain) : Response {               
        val request = chain.request().newBuilder()
            .header("x-custom-header", "my-value")
            .build()
        return chain.proceed(request)
    }
}
Alex Nolasco
sumber
9

Jika Anda menggunakan pustaka Retrofit maka Anda dapat langsung meneruskan permintaan header ke api menggunakan @Headeranotasi tanpa menggunakan Interceptor. Berikut adalah contoh yang menunjukkan cara menambahkan header ke permintaan api Retrofit.

@POST(apiURL)
void methodName(
        @Header(HeadersContract.HEADER_AUTHONRIZATION) String token,
        @Header(HeadersContract.HEADER_CLIENT_ID) String token,
        @Body TypedInput body,
        Callback<String> callback);

Semoga membantu!

Rajesh
sumber
4
Saya tahu itu, tetapi saya memiliki metode untuk mendapatkan token bernama: getToken () yang telah menunggu di utas. jadi jika saya memanggilnya di pencegat OkHttp, itu akan berjalan di utas retrofit dan saya tidak perlu khawatir tentang masalah utas.
Morteza Rastgoo
6

Masih ada cara lain untuk menambahkan interseptor di OkHttp3 Anda (versi terbaru saat ini), yaitu Anda menambahkan interseptor ke pembuat Okhttp Anda

okhttpBuilder.networkInterceptors().add(chain -> {
 //todo add headers etc to your AuthorisedRequest

  return chain.proceed(yourAuthorisedRequest);
});

dan terakhir buat okHttpClient Anda dari pembuat ini

OkHttpClient client = builder.build();
Kushagar Lall
sumber
ya, tidak memperhatikan bagian tentang add*Network*Interceptoralih - alih addInterceptormembuat saya menarik rambut saya selama beberapa jam :)
Antek
1

Ini berhasil untuk saya:

class JSONHeaderInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain) : Response {
        val request = chain.request().newBuilder()
            .header("Content-Type", "application/json")
            .build()
        return chain.proceed(request)
    }
}
fun provideHttpClient(): OkHttpClient {
    val okHttpClientBuilder = OkHttpClient.Builder()
    okHttpClientBuilder.addInterceptor(JSONHeaderInterceptor())
    return okHttpClientBuilder.build()
}
patrick-fitzgerald
sumber
0
package com.example.network.interceptors;

import androidx.annotation.NonNull;

import java.io.IOException;
import java.util.Map;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class RequestHeadersNetworkInterceptor implements Interceptor {

    private final Map<String, String> headers;

    public RequestHeadersNetworkInterceptor(@NonNull Map<String, String> headers) {
        this.headers = headers;
    }

    @NonNull
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();
        for (Map.Entry<String, String> header : headers.entrySet()) {
            if (header.getKey() == null || header.getKey().trim().isEmpty()) {
                continue;
            }
            if (header.getValue() == null || header.getValue().trim().isEmpty()) {
                builder.removeHeader(header.getKey());
            } else {
                builder.header(header.getKey(), header.getValue());
            }
        }
        return chain.proceed(builder.build());
    }

}

Contoh penggunaan:

httpClientBuilder.networkInterceptors().add(new RequestHeadersNetworkInterceptor(new HashMap<String, String>()
{
    {
        put("User-Agent", getUserAgent());
        put("Accept", "application/json");
    }
}));
MingalevME
sumber
0
client = new OkHttpClient();

        Request request = new Request.Builder().header("authorization", token).url(url).build();
        MyWebSocketListener wsListener = new MyWebSocketListener(LudoRoomActivity.this);
        client.newWebSocket(request, wsListener);
        client.dispatcher().executorService().shutdown();
Pankaj Sharma
sumber