87 votes

Android Retrofit @Headers paramétrés

J'utilise OAuth et je dois mettre le jeton OAuth dans mon en-tête chaque fois que je fais une demande. Je vois le @Header mais existe-t-il un moyen de la paramétrer pour que je puisse la passer au moment de l'exécution ?

Voici le concept

@Header({Authorization:'OAuth {var}', api_version={var} })

Pouvez-vous les transmettre au moment de l'exécution ?

@GET("/users")
void getUsers(
    @Header("Authorization") String auth, 
    @Header("X-Api-Version") String version, 
    Callback<User> callback
)

100voto

Felix Points 796

En plus d'utiliser le paramètre @Header, je préfère utiliser RequestInterceptor pour mettre à jour toutes vos requêtes sans changer votre interface. En utilisant quelque chose comme :

RestAdapter.Builder builder = new RestAdapter.Builder()
    .setRequestInterceptor(new RequestInterceptor() {
        @Override
        public void intercept(RequestFacade request) {
            request.addHeader("Accept", "application/json;versions=1");
            if (isUserLoggedIn()) {
                request.addHeader("Authorization", getToken());
            }                    
        }
    });

p/s : Si vous utilisez Retrofit2, vous devez utiliser Interceptor au lieu de RequestInterceptor

Depuis RequestInterceptor n'est plus disponible dans Retrofit 2.0

56voto

nana Points 1040

Oui, vous pouvez les passer en cours d'exécution. En fait, à peu près exactement comme vous l'avez tapé. Ce serait dans votre classe d'interface API, nommée par exemple SecretApiInterface.java

public interface SecretApiInterface {

    @GET("/secret_things")
    SecretThing.List getSecretThings(@Header("Authorization") String token)

}

Ensuite, vous passez les paramètres à cette interface à partir de votre requête, quelque chose de ce genre : (ce fichier serait par exemple SecretThingRequest.java )

public class SecretThingRequest extends RetrofitSpiceRequest<SecretThing.List, SecretApiInteface>{

    private String token;

    public SecretThingRequest(String token) {
        super(SecretThing.List.class, SecretApiInterface.class);
        this.token = token;
    }

    @Override
    public SecretThing.List loadDataFromNetwork() {
        SecretApiInterface service = getService();
        return service.getSecretThings(Somehow.Magically.getToken());
    }
}

Dónde Somehow.Magically.getToken() est un appel de méthode qui renvoie un jeton, à vous de voir où et comment vous le définissez.

Vous pouvez bien sûr avoir plus d'un @Header("Blah") String blah dans l'implémentation de l'interface, comme dans votre cas !

Je l'ai trouvé déroutant aussi, la documentation le dit clairement remplace l'en-tête, mais il DOESN'T ¡!
Il est en effet ajouté comme avec @Headers("hardcoded_string_of_liited_use") annotation

J'espère que cela vous aidera ;)

38voto

pablisco Points 2478

La réponse acceptée est pour une ancienne version de Retrofit. Pour les futurs spectateurs, la façon de faire avec Retrofit 2.0 utilise un client OkHttp personnalisé :

OkHttpClient httpClient = new OkHttpClient.Builder()
  .addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
      Builder ongoing = chain.request().newBuilder();
      ongoing.addHeader("Accept", "application/json;versions=1");
      if (isUserLoggedIn()) {
        ongoing.addHeader("Authorization", getToken());
      }
      return chain.proceed(ongoing.build());
    }
  })
  .build();

Retrofit retrofit = new Retrofit.Builder()
  // ... extra config
  .client(httpClient)
  .build();

J'espère que cela aidera quelqu'un :)

8voto

Soon Santos Points 1001

Retrofit 2.3.0

OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder
            .addInterceptor(new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    Request.Builder newRequest = request.newBuilder().header("Authorization", accessToken);
                    return chain.proceed(newRequest.build());
                }
            });

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(GithubService.BASE_URL)
            .client(okHttpClientBuilder.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

Je l'utilise pour me connecter à GitHub.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X