Używam OAuth i za każdym razem, gdy wysyłam żądanie, muszę umieszczać token OAuth w nagłówku. Widzę @Header
adnotację, ale czy istnieje sposób na sparametryzowanie jej, aby można było ją przekazać w czasie wykonywania?
Oto koncepcja
@Header({Authorization:'OAuth {var}', api_version={var} })
Czy możesz przekazać je w Runtime?
@GET("/users")
void getUsers(
@Header("Authorization") String auth,
@Header("X-Api-Version") String version,
Callback<User> callback
)
java
android
annotations
retrofit
jpotts18
źródło
źródło
Odpowiedzi:
Oprócz używania parametru @Header, wolałbym raczej używać RequestInterceptor do aktualizowania wszystkich żądań bez zmiany interfejsu. Używając czegoś takiego:
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: Jeśli używasz Retrofit2, powinieneś użyć
Interceptor
zamiastRequestInterceptor
Ponieważ
RequestInterceptor
nie jest już dostępny w Retrofit 2.0źródło
RestAdapter
zależy od Retrofit1, w Retrofit2 jestRetrofit
. Zamierzam użyć Retrofit2, więc nie ma problemów, jeśli użyjęRequestInterceptor
jak powyżej kodu?Tak, możesz je przekazać w czasie wykonywania. Prawdę mówiąc, prawie dokładnie tak, jak to wpisałeś. Byłoby to w twojej klasie interfejsu API, o nazwie powiedz SecretApiInterface.java
public interface SecretApiInterface { @GET("/secret_things") SecretThing.List getSecretThings(@Header("Authorization") String token) }
Następnie przekazujesz parametry do tego interfejsu ze swojego żądania, coś w tym stylu: (ten plik będzie na przykład 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()); } }
Gdzie
Somehow.Magically.getToken()
jest wywołanie metody, która zwraca token, od Ciebie zależy, gdzie i jak ją zdefiniujesz.Oczywiście możesz mieć więcej niż jedną
@Header("Blah") String blah
adnotację w implementacji interfejsu, tak jak w twoim przypadku!Wydało mi się to również zagmatwane, dokumentacja wyraźnie mówi, że zastępuje nagłówek, ale NIE !
W rzeczywistości jest dodawany jak w przypadku
@Headers("hardcoded_string_of_liited_use")
adnotacjiMam nadzieję że to pomoże ;)
źródło
Zaakceptowana odpowiedź dotyczy starszej wersji Retrofit. Dla przyszłych widzów sposobem na to w
Retrofit
wersji 2.0 jest użycie niestandardowego klienta OkHttp: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();
Mam nadzieję, że to komuś pomoże. :)
źródło
Interceptor
do którego możesz ustawić lub zresetować przechwytywacz na późniejszym etapie. Jednak argumentowałbym, że modernizacja jako singleton może być oznaką wczesnej optymalizacji. Nie ma narzutów na tworzenie nowej instancji modernizacji: github.com/square/retrofit/blob/master/retrofit/src/main/java/ ...Interceptor
po utworzeniu instancji Retrofit2.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();
Używam tego do łączenia się z GitHubem.
źródło