webentwicklung-frage-antwort-db.com.de

Android Retrofit Parametrized @Headers

Ich verwende OAuth und muss bei jeder Anfrage das OAuth= Token in meinen Header schreiben. Ich sehe die @Header - Anmerkung , aber gibt es eine Möglichkeit, es zu parametrisieren, damit ich zur Laufzeit übergeben kann?

Hier ist das Konzept

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

Können Sie sie zur Laufzeit weitergeben?

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

Neben der Verwendung des @Header-Parameters würde ich lieber RequestInterceptor verwenden, um alle Ihre Anforderungen zu aktualisieren, ohne die Benutzeroberfläche zu ändern. Mit etwas wie:

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: Wenn Sie Retrofit2 verwenden, sollten Sie Interceptor anstelle von RequestInterceptor bemerken

Seit RequestInterceptor ist in Retrofit 2.0 nicht mehr verfügbar

92
Felix

Ja, Sie können sie zur Laufzeit übergeben. Eigentlich ziemlich genau so, wie Sie es getippt haben. Dies befindet sich in Ihrer API-Schnittstellenklasse mit dem Namen say SecretApiInterface.Java .

public interface SecretApiInterface {

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

}

Dann übergeben Sie die Parameter von Ihrer Anfrage an diese Schnittstelle, etwa so: (Diese Datei wäre zum Beispiel 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());
    }
}

Wo Somehow.Magically.getToken() ein Methodenaufruf ist, der ein Token zurückgibt, liegt es an Ihnen, wo und wie Sie es definieren.

Sie können natürlich mehr als eine @Header("Blah") String blah -Anmerkung in der Schnittstellenimplementierung haben, wie in Ihrem Fall !

Ich fand es auch verwirrend, die Dokumentation sagt klar ersetzt den Header, aber es NICHT !
Es wird tatsächlich wie bei der Annotation @Headers("hardcoded_string_of_liited_use") hinzugefügt

Hoffe das hilft ;)

51
nana

Die akzeptierte Antwort bezieht sich auf eine ältere Version von Retrofit. Für zukünftige Betrachter verwendet die Möglichkeit, dies mit Retrofit 2.0 zu tun, einen benutzerdefinierten OkHttp-Client:

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

Hoffe es hilft jemandem. :)

34
pablisco

Nachrüstung 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();

Ich benutze dies, um eine Verbindung zu GitHub herzustellen.

5
Soon Santos