¿Cómo agregar encabezados al interceptor de solicitudes OkHttp?

95

Tengo este interceptor que agrego a mi cliente OkHttp:

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;
}
}

¿Cómo puedo agregar encabezados para solicitar en mi interceptor?

Intenté esto pero estoy cometiendo un error y pierdo mi solicitud al crear una nueva solicitud:

    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);
    }
}

Tenga en cuenta que, sé que puedo agregar un encabezado al crear una solicitud como esta:

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();

Pero no se ajusta a mis necesidades. Lo necesito en interceptor.

Morteza Rastgoo
fuente
1
Tu interceptor parece correcto. ¿Qué no funciona con eso?
Jesse Wilson

Respuestas:

153

Finalmente, agregué los encabezados de esta manera:

@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
fuente
1
¿Por alguna razón esto no agrega los encabezados a mi solicitud? Estoy usando okHttp.Builder y networkInterceptors (). Add (interceptor) con el mismo código que en esta respuesta, pero los encabezados no se agregan.
Informatic0re
¿Cómo agregar un encabezado para la solicitud de YouTube? ¿Es un nombre de paquete y su clave de API y luego pasar.addheader(params1, params2);
RoCk RoCk
@RoCk Puede tener RestClients separados que tengan una configuración de encabezado diferente.
Morteza Rastgoo
27

puedes hacerlo de esta manera

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
fuente
5
Este no es un interceptor.
bekce
15

aquí hay una esencia útil de 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
fuente
10

Enfrenté un problema similar con otras muestras, esta clase de Kotlin funcionó para mí

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
fuente
9

Si está utilizando la biblioteca Retrofit, puede pasar directamente el encabezado a la solicitud de API mediante la @Headeranotación sin el uso de Interceptor. Aquí hay un ejemplo que muestra cómo agregar un encabezado a la solicitud de API de Retrofit.

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

¡Espero eso ayude!

Rajesh
fuente
4
Lo sé, pero tengo un método para obtener el token llamado: getToken () que tiene esperar en el hilo. Entonces, si llamo a eso en el interceptor OkHttp, se ejecutará en el subproceso de actualización y no tengo que preocuparme por los problemas del subproceso.
Morteza Rastgoo
6

Hay otra forma de agregar interceptores en su OkHttp3 (última versión a partir de ahora), es decir, agrega los interceptores a su constructor Okhttp

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

  return chain.proceed(yourAuthorisedRequest);
});

y finalmente construya su okHttpClient a partir de este constructor

OkHttpClient client = builder.build();
Kushagar Lall
fuente
sí, sin darme cuenta de la parte en add*Network*Interceptorlugar de addInterceptortenerme tirando de mi cabello durante un par de horas :)
Antek
1

Esto funcionó para mí:

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
fuente
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());
    }

}

Ejemplo de uso:

httpClientBuilder.networkInterceptors().add(new RequestHeadersNetworkInterceptor(new HashMap<String, String>()
{
    {
        put("User-Agent", getUserAgent());
        put("Accept", "application/json");
    }
}));
MingalevME
fuente
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
fuente