Я использую OAuth, и мне нужно помещать токен OAuth в свой заголовок каждый раз, когда я делаю запрос. Я вижу аннотацию @Header
, но есть ли способ ее параметризации, чтобы я мог пройти во время выполнения?
Вот понятие
@Header({Authorization:'OAuth {var}', api_version={var} })
Можете ли вы передать их в Runtime?
@GET("/users")
void getUsers(
@Header("Authorization") String auth,
@Header("X-Api-Version") String version,
Callback<User> callback
)
Ответ 1
Помимо использования параметра @Header, я бы предпочел использовать RequestInterceptor, чтобы обновить все ваши запросы без изменения интерфейса. Используя что-то вроде:
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: если вы используете Retrofit2, вы должны использовать Interceptor
вместо RequestInterceptor
Поскольку RequestInterceptor
больше не доступен в Retrofit 2.0
Ответ 2
Да, вы можете передать их во время выполнения. На самом деле, в значительной степени точно так же, как вы его напечатали. Это будет в вашем интерфейсном интерфейсе API, называемом say SecretApiInterface.java
public interface SecretApiInterface {
@GET("/secret_things")
SecretThing.List getSecretThings(@Header("Authorization") String token)
}
Затем вы передаете параметры этому интерфейсу из вашего запроса, что-то вдоль этих строк: (этот файл будет, например, 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()
- вызов метода, который возвращает токен, зависит от вас, где и как вы его определяете.
Конечно, вы можете иметь несколько аннотаций @Header("Blah") String blah
в реализации интерфейса, как в вашем случае!
Я тоже смущаюсь, документация четко говорит, что заменяет заголовок, но он НЕ!
Фактически это добавляется как с аннотацией @Headers("hardcoded_string_of_liited_use")
Надеюсь, что это поможет;)
Ответ 3
Принятый ответ - для более старой версии Retrofit. Для будущих зрителей способ сделать это с помощью Retrofit
2.0 - это использование пользовательского клиента 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();
Надеюсь, это поможет кому-то.:)
Ответ 4
Дооснащение 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();
Я использую это для подключения к GitHub.