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.