2015-04-26 12 views
30

Używam interfejsu API korzystającego ze schematu autoryzacji, który wymaga ustawienia specjalnego nagłówka "X-Authorization" w celu uwierzytelnienia żądania. Na przykład, ta konfiguracja Modernizacja działa idealnie dla użytkownika, którego auth Token jest abc123:Jak dynamicznie ustawiać nagłówki w Retroficie (Android)

@Headers("X-Authorization: abc123") 
@GET("/posts") 
Observable<List<Post>> get_posts(); 

I buforować X-autoryzacji tokenu użytkownika, więc mam dostęp do tego jednak, że nie można po prostu wrzucić go deklaracja @Headers.

@Headers("X-Authorization: " + token) 
@GET("/posts") 
Observable<List<Post>> get_posts(); 

otrzymuję błąd kompilacji tutaj: Error:(41, 34) error: element value must be a constant expression

Wszelkie pomysły, w jaki sposób mogę to obejść?

Odpowiedz

56

Od Retrofit 2.0 masz dwie opcje


1) Korzystanie OkHttp 2.2+ używać Interceptor

Na poziomie HTTP, masz większą kontrolę nad tym wnioskiem, więc można robić takie rzeczy jak stosowaniu nagłówki tylko do konkretnego żądania złożonego do określonego punktu końcowego i tak dalej.

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

Edytuj: Dodawanie @JakeWarthon komentarz jako innej opcji, jak również ważne.

2) Wpisz @Header dla parametru metody i przekaż go jako wartość podczas wywoływania.

Z docs:

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

parametry nagłówka może być null które pomijają je od wniosku. Przekazanie listy lub tablicy spowoduje wygenerowanie nagłówka dla każdego niezerowego elementu.

Uwaga: nagłówki nie zastępują się nawzajem. Wszystkie nagłówki o tej samej nazwie zostaną uwzględnione w żądaniu.


EDIT: Ta opcja nie powinna być traktowana jako Retrofit 2. * spadło poparcie dla przechwytujących.

3) Użytkownik modernizacyjny RequestInterceptor

Od docs: Intercept każde żądanie, zanim zostanie wykonany, aby dodać dodatkowe dane.

Można zrobić coś takiego

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

„problem” z tego podejścia jest to, że przechwytujących dostanie wykonywane na wszystkich punktów końcowych, jak to ustalono na poziomie RestAdapter, a nie za punktem końcowym.Ponadto, RequestFacade nie ujawnia zbyt wielu informacji o żądaniu, więc nie ma szans na dodanie do niego większej logiki.

+0

Doskonała odpowiedź. Dzięki za to. – johncorser

+0

Nie znaleziono odnośnika w pierwszej opcji: '1) Zmodernizowany użytkownik RequestInterceptor' ... czy korekta? – Bhuro

Powiązane problemy