Saltar al contenido

Cómo establecer encabezados dinámicamente en Retrofit (Android)

Si hallas algún problema con tu código o trabajo, recuerda probar siempre en un entorno de testing antes añadir el código al proyecto final.

Solución:

Desde Retrofit 2.0 tienes dos opciones


1) Usando OkHttp 2.2+ use Interceptor

En el nivel Http, tiene más control sobre la solicitud, por lo que puede hacer cosas como aplicar encabezados solo a una solicitud específica realizada a un punto final específico, etc.

public class MyOkHttpInterceptor implements Interceptor {

@Override
public Response intercept(Chain chain) throws IOException 
    Request originalRequest = chain.request();
    if (!"/posts".contains(originalRequest.url()) ) 
        return chain.proceed(originalRequest);
    

    String token = // get token logic 

    Request newRequest = originalRequest.newBuilder()
        .header("X-Authorization", token)
        .build();

    return chain.proceed(newRequest);


[...]

OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.networkInterceptors().add(new MyOkHttpInterceptor());
OkClient okClient = new OkClient(okHttpClient);
YourApi api = new RestAdapter.Builder()
            .setEndpoint(url)
            .setClient(okClient)
            .build()
            .create(YourApi.class);

Editar: Agregar el comentario de @JakeWarthon como otra opción, ya que también es válido.

2) Coloque @Header en un parámetro de método y páselo como un valor al invocarlo.

De los documentos:

// Replaces the header with the the value of its target.
@GET("/")
void foo(@Header("Accept-Language") String lang, Callback cb);

Los parámetros del encabezado pueden ser null que los omitirá de la solicitud. Pasando una Lista o array dará como resultado un encabezado para cada no-null ít.

Nota: los encabezados no se sobrescriben entre sí. Todos los encabezados con el mismo nombre se incluirán en la solicitud.


EDITAR: Esta opción no debe considerarse como Retrofit 2.* Se eliminó el soporte para interceptores.

3) RequestInterceptor de actualización del usuario

De los documentos:
Intercepte cada solicitud antes de que se ejecute para agregar datos adicionales.

Podrías hacer algo como

public class MyRetrofitInterceptor implements RequestInterceptor {

@Override
public void intercept(RequestFacade req) 
    String token = // get token logic 
    if (token != null) 
        req.addHeader("X-Authorization", token);
    


[...]

YourApi api = new RestAdapter.Builder()
            .setEndpoint(url)
            .setRequestInterceptor(new MyRetrofitInterceptor())
            .build()
            .create(YourApi.class);

El “problema” con este enfoque es que el interceptor se ejecutará en todos los puntos finales, ya que está configurado en el nivel de RestAdapter, y no por punto final. También el RequestFacade no expone mucha información sobre la solicitud, por lo que no hay posibilidad de agregar mucha lógica a su alrededor.

Pasar el encabezado en el parámetro sería útil. Mira el siguiente código;

 @GET("/posts")
Observable getDataFromService(
        @HeaderMap Map headers,
        @QueryMap HashMap queryParams
);

        hashMap1.put("Authorization", token);
    return ApiService.getAPI_test().getDataFromService(hashMap1, url, hashMap)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io());

Actualizar:

Más mejor sería

 @GET("/posts")
Observable getDataFromService(
        @Header("Authorization") token: String = "Bearer " + PreferenceUtils.getToken(),
        @QueryMap HashMap queryParams
);

Encabezado dinámico en Retrofit 2

He luchado demasiado para agregar Dynamic Header In Retrofit 2.

He revisado tantos blogs y el flujo de StackOver. Todo el mundo ha mostrado ejemplo con Interceptor.

Y no es algo inteligente, solo para una llamada API necesitamos hacer tanto trabajo.

solo tienes que agregar @HeaderMap como argumento de diversión. Lo he hecho de una manera muy simple: –

En Kotlin

    val headers = HashMap()
    headers["KEY_AUTHORIZATION"] = "paste AUTHORIZATION value here"
    headers["KEY_TOKEN"] = "paste TOKEN value here"

    val jsonObject= JsonObject()

I am passing here header and other data also
Calling of fun:-

postEvent(headers,jsonObject)

API Declaration 

    @POST("/v1/post_data")
    fun postEvent(@HeaderMap headers: Map, @Body jsonObject: JsonObject): Call

API Declaration with RxAndroid

    @POST("/v1/post_data")
    fun postEvent(@HeaderMap headers: Map, @Body jsonObject: JsonObject): Single

Segundo argumento aquí tengo JsonObject. Puede reemplazar con cualquier cosa que necesite pasar o también puede eliminarlo.

en Java

 HashMap headers = new HashMap();
    headers.put("KEY_AUTHORIZATION","paste AUTHORIZATION value here");
    headers.put("KEY_TOKEN", "paste TOKEN value here");

    JsonObject jsonObject= new JsonObject();

I am passing here header and other data also

Calling of fun:-
postEvent(headers,jsonObject);

    API Declaration 
    @POST("/v1/post_data")
    Call postEvent(@HeaderMap Map headers, @Body JsonObject jsonObject);

API Declaration with RxAndroid

    @POST("/v1/post_data")
    Single postEvent(@HeaderMap Map headers, @Body JsonObject jsonObject);

Segundo argumento aquí tengo JsonObject. Puede reemplazar con cualquier cosa que necesite pasar o también puede eliminarlo.

Te mostramos las comentarios y valoraciones de los lectores

Agradecemos que desees corroborar nuestro análisis ejecutando un comentario o valorándolo te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *