web-dev-qa-db-fra.com

Android Retrofit Parameterized @Headers

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

Voici le concept

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

Pouvez-vous les transmettre au runtime?

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

En plus d'utiliser le paramètre @Header, je préfère utiliser RequestInterceptor pour mettre à jour toute votre requête 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 devriez remarquer Interceptor au lieu de RequestInterceptor

Puisque RequestInterceptor n'est plus disponible dans Retrofit 2.0

92
Felix

Oui, vous pouvez les transmettre au moment de l'exécution. En fait, à peu près exactement comme vous l'avez tapé. Ce serait dans votre classe d'interface API, nommée say SecretApiInterface.Java

public interface SecretApiInterface {

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

}

Ensuite, vous transmettez les paramètres de cette requête à cette interface, par exemple: (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());
    }
}

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

Vous pouvez bien sûr avoir plusieurs annotations @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 NE FAIT PAS !
Il est en fait ajouté comme avec @Headers("hardcoded_string_of_liited_use") annotation

J'espère que cela t'aides ;)

51
nana

La réponse acceptée concerne une ancienne version de Retrofit. Pour les futurs téléspectateurs, la manière de procéder avec Retrofit 2.0 consiste à utiliser 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 ça aide quelqu'un. :)

34
pablisco

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

J'utilise ceci pour me connecter à GitHub.

5
Soon Santos