Agregar encabezado a todas las solicitudes con Retrofit 2


129

La documentación de Retrofit 2 dice:

Los encabezados que deben agregarse a cada solicitud se pueden especificar utilizando un interceptor OkHttp.

Se puede hacer fácilmente usando la versión anterior, aquí está el control de calidad relacionado.

Pero el uso de reequipamiento 2, no pude encontrar algo parecido setRequestInterceptoro setInterceptormétodo que se puede aplicar a Retrofit.Builderobjetos.

También parece que no hay RequestInterceptoren OkHttp más. El documento de Retrofit nos remite a Interceptor que no entendí bien cómo usarlo para este propósito.

¿Cómo puedo hacer esto?

Respuestas:


200
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

httpClient.addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request().newBuilder().addHeader("parameter", "value").build();
        return chain.proceed(request);
    }
});
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(url).client(httpClient.build()).build();

55
En la versión retrofit2-beta3 es un poco diferente. Ver aquí: stackoverflow.com/questions/34973432/…
Ashkan Sarlak

¿Cómo podemos confirmar que se envían estos encabezados? Cuando depuro en Call enqueueno puedo ver los encabezados predeterminados.
víbora

Debería ser new OkHttpClient.Builder()en su lugarnew OkHttpClient()
Wojtek

80

La última versión de actualización AQUÍ -> 2.1.0.

versión lambda:

  builder.addInterceptor(chain -> {
    Request request = chain.request().newBuilder().addHeader("key", "value").build();
    return chain.proceed(request);
  });

versión larga fea:

  builder.addInterceptor(new Interceptor() {
    @Override public Response intercept(Chain chain) throws IOException {
      Request request = chain.request().newBuilder().addHeader("key", "value").build();
      return chain.proceed(request);
    }
  });

versión completa:

class Factory {

public static APIService create(Context context) {

  OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
  builder.readTimeout(10, TimeUnit.SECONDS);
  builder.connectTimeout(5, TimeUnit.SECONDS);

  if (BuildConfig.DEBUG) {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
    builder.addInterceptor(interceptor);
  }

  builder.addInterceptor(chain -> {
    Request request = chain.request().newBuilder().addHeader("key", "value").build();
    return chain.proceed(request);
  });

  builder.addInterceptor(new UnauthorisedInterceptor(context));
  OkHttpClient client = builder.build();

  Retrofit retrofit =
      new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();

  return retrofit.create(APIService.class);
  }
}

archivo gradle (debe agregar el interceptor de registro si planea usarlo):

  //----- Retrofit
  compile 'com.squareup.retrofit2:retrofit:2.1.0'
  compile "com.squareup.retrofit2:converter-gson:2.1.0"
  compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"
  compile 'com.squareup.okhttp3:logging-interceptor:3.4.0'

13

Para registrar su solicitud y respuesta, necesita un interceptor y también para configurar el encabezado, necesita un interceptor. Aquí está la solución para agregar ambos interceptores a la vez usando la actualización 2.1.

 public OkHttpClient getHeader(final String authorizationValue ) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient okClient = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .addNetworkInterceptor(
                        new Interceptor() {
                            @Override
                            public Response intercept(Interceptor.Chain chain) throws IOException {
                                Request request = null;
                                if (authorizationValue != null) {
                                    Log.d("--Authorization-- ", authorizationValue);

                                    Request original = chain.request();
                                    // Request customization: add request headers
                                    Request.Builder requestBuilder = original.newBuilder()
                                            .addHeader("Authorization", authorizationValue);

                                    request = requestBuilder.build();
                                }
                                return chain.proceed(request);
                            }
                        })
                .build();
        return okClient;

    }

Ahora en su objeto de actualización agregue este encabezado en el cliente

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .client(getHeader(authorizationValue))
                .addConverterFactory(GsonConverterFactory.create())
                .build();

12

Pruebe este tipo de encabezado para Retrofit 1.9 y 2.0. Para tipo de contenido Json.

@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);

Puede agregar muchos más encabezados, es decir

@Headers({
        "Accept: application/json",
        "User-Agent: Your-App-Name",
        "Cache-Control: max-age=640000"
    })

Añadir dinámicamente a los encabezados:

@POST("user/classes")
Call<ResponseModel> addToPlaylist(@Header("Content-Type") String content_type, @Body RequestModel req);

Llame a su método, es decir

mAPI.addToPlayList("application/json", playListParam);

O

Quiere pasar cada vez y luego crear un objeto HttpClient con http Interceptor:

OkHttpClient httpClient = new OkHttpClient();
        httpClient.networkInterceptors().add(new Interceptor() {
            @Override
            public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
                Request.Builder requestBuilder = chain.request().newBuilder();
                requestBuilder.header("Content-Type", "application/json");
                return chain.proceed(requestBuilder.build());
            }
        });

Luego agregue al objeto de actualización

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(httpClient).build();

ACTUALIZAR si está utilizando Kotlin, elimine el { }resto, no funcionará


2
¿Cómo hacer un encabezado para todas las solicitudes en la interfaz sin duplicarlo?
Evgenii Vorobei

Debe agregarlo en el interceptor de registro HTTP
Avinash Verma

6

En mi caso addInterceptor()no funcionó para agregar encabezados HTTP a mi solicitud, tuve que usar addNetworkInterceptor(). El código es el siguiente:

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addNetworkInterceptor(new AddHeaderInterceptor());

Y el código interceptor:

public class AddHeaderInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        Request.Builder builder = chain.request().newBuilder();
        builder.addHeader("Authorization", "MyauthHeaderContent");

        return chain.proceed(builder.build());
    }
}

Esto y más ejemplos sobre esta esencia


5

Si usa el método addInterceptor para agregar HttpLoggingInterceptor, no registrará las cosas que agregaron otros interceptores aplicados después de HttpLoggingInterceptor.

Por ejemplo: si tiene dos interceptores "HttpLoggingInterceptor" y "AuthInterceptor", y HttpLoggingInterceptor se aplica primero, entonces no puede ver los parámetros http o los encabezados establecidos por AuthInterceptor.

OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());

Lo resolví mediante el método addNetworkInterceptor.


1
También puede agregar HttpLoggingInterceptorcomo último interceptor para ver la solicitud final.
Micer

2

Utilice este cliente de modificación

class RetrofitClient2(context: Context) : OkHttpClient() {

    private var mContext:Context = context
    private var retrofit: Retrofit? = null

    val client: Retrofit?
        get() {
            val logging = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)

            val client = OkHttpClient.Builder()
                    .connectTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
                    .readTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
                    .writeTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
            client.addInterceptor(logging)
            client.interceptors().add(AddCookiesInterceptor(mContext))

            val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create()
            if (retrofit == null) {

                retrofit = Retrofit.Builder()
                        .baseUrl(Constants.URL)
                        .addConverterFactory(GsonConverterFactory.create(gson))
                        .client(client.build())
                        .build()
            }
            return retrofit
        }
}

Estoy pasando el JWT junto con cada solicitud. No te preocupes por los nombres de las variables, es un poco confuso.

class AddCookiesInterceptor(context: Context) : Interceptor {
    val mContext: Context = context
    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val builder = chain.request().newBuilder()
        val preferences = CookieStore().getCookies(mContext)
        if (preferences != null) {
            for (cookie in preferences!!) {
                builder.addHeader("Authorization", cookie)
            }
        }
        return chain.proceed(builder.build())
    }
}

1

En kotlin, agregar interceptor se ve de esa manera:

.addInterceptor{ it.proceed(it.request().newBuilder().addHeader("Cache-Control", "no-store").build())}

0

La biblioteca RetrofitHelper escrita en kotlin, le permitirá hacer llamadas a la API, usando unas pocas líneas de código.

Agregue encabezados en su clase de aplicación como este:

class Application : Application() {

    override fun onCreate() {
    super.onCreate()

        retrofitClient = RetrofitClient.instance
                    //api url
                .setBaseUrl("https://reqres.in/")
                    //you can set multiple urls
        //                .setUrl("example","http://ngrok.io/api/")
                    //set timeouts
                .setConnectionTimeout(4)
                .setReadingTimeout(15)
                    //enable cache
                .enableCaching(this)
                    //add Headers
                .addHeader("Content-Type", "application/json")
                .addHeader("client", "android")
                .addHeader("language", Locale.getDefault().language)
                .addHeader("os", android.os.Build.VERSION.RELEASE)
            }

        companion object {
        lateinit var retrofitClient: RetrofitClient

        }
    }  

Y luego haz tu llamada:

retrofitClient.Get<GetResponseModel>()
            //set path
            .setPath("api/users/2")
            //set url params Key-Value or HashMap
            .setUrlParams("KEY","Value")
            // you can add header here
            .addHeaders("key","value")
            .setResponseHandler(GetResponseModel::class.java,
                object : ResponseHandler<GetResponseModel>() {
                    override fun onSuccess(response: Response<GetResponseModel>) {
                        super.onSuccess(response)
                        //handle response
                    }
                }).run(this)

Para más información ver la documentación


0

La versión de Kotlin sería

fun getHeaderInterceptor():Interceptor{
    return object : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val request =
            chain.request().newBuilder()
                    .header(Headers.KEY_AUTHORIZATION, "Bearer.....")
                    .build()
            return chain.proceed(request)
        }
    }
}


private fun createOkHttpClient(): OkHttpClient {
    return OkHttpClient.Builder()
            .apply {
                if(BuildConfig.DEBUG){
                    this.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
                }
            }
            .addInterceptor(getHeaderInterceptor())
            .build()
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.