我使用这个来配置我的Retrofit:
注意:
1. 在使用Retrofit发出任何请求之前都会调用此方法。
2. 我阅读了这篇文章,知道可以在请求失败后刷新令牌,但出于业务原因,我希望避免使用无效令牌。
3. 我在我的Activity中调用
更新:我向新的OkHttp添加了以下
RestAdapter restAdapter = new RestAdapter.Builder()
//add headers to requests
.setRequestInterceptor(getAuthenticatedRequestInterceptor())
.setEndpoint(BASE_URL)
.setConverter(new GsonConverter(getGson()))
.build();
getAuthenticatedRequestInterceptor()方法会向请求添加头信息:
public AccountRequestInterceptor getAuthenticatedRequestInterceptor() {
AccountRequestInterceptor interceptor = new AccountRequestInterceptor();
Map<String, String> headers = new HashMap<>();
String accessToken = null;
try {
accessToken = TokenProvider.getInstance(mContext).getToken();
} catch (InterruptedException e) {
}
headers.put(HeadersContract.HEADER_AUTHONRIZATION, O_AUTH_AUTHENTICATION + accessToken);
interceptor.setHeader(headers);
return interceptor;
}
getToken()
方法是:
private synchronized string getToken() throws InterruptedException {
if (!isRefreshing()) {
//This is very important to call notify() on the same object that we call wait();
final TokenProvider myInstance = this;
setRefreshing(true);
MyApplication.getRestClient().getAccountService().getRefreshedToken(mLoginData.getRefreshToken())
.subscribe(new Observer<LoginResponse>() {
@Override
public void onCompleted() {
synchronized (myInstance) {
setRefreshing(false);
myInstance.notifyAll();
}
}
@Override
public void onError(Throwable e) {
synchronized (myInstance) {
setRefreshing(false);
myInstance.notifyAll();
}
}
@Override
public void onNext(LoginResponse loginResponse) {
synchronized (myInstance) {
mLoginData = loginResponse;
mAccountProvider.saveLoginData(loginResponse);
myInstance.notifyAll();
}
}
});
}
this.wait();
return mLoginData.getToken();
}
TokenProvider.getInstance(mContext).getToken()
方法在主线程上调用wait()
以获取来自异步方法的响应。虽然这是一件不好的事情,但我需要在此处等待响应以获取令牌并返回令牌。如何在单独的线程中执行此操作以避免在主线程上等待?注意:
1. 在使用Retrofit发出任何请求之前都会调用此方法。
2. 我阅读了这篇文章,知道可以在请求失败后刷新令牌,但出于业务原因,我希望避免使用无效令牌。
3. 我在我的Activity中调用
MyApplication.getRestClient().getAccountService().login(loginRequest,callback...)
,并且在添加令牌之前所有操作都在后台线程中进行。因此,我想使用我的令牌并且不阻塞主线程。更新:我向新的OkHttp添加了以下
Interceptor
:public class RequestTokenInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Request newRequest;
try {
Log.d("addHeader", "Before");
String token = TokenProvider.getInstance(mContext).getToken();
if (token != null) {
newRequest = request.newBuilder()
.addHeader("Bearer", token)
.build();
} else {
// I want to cancel the request or raise an exception to catch it in onError method
// of retrofit callback.
}
} catch (InterruptedException e) {
Log.d("addHeader", "Error");
e.printStackTrace();
return chain.proceed(request);
}
Log.d("addHeader", "after");
return chain.proceed(newRequest);
}
}
如果令牌为空,我如何取消请求或引发异常以在Retrofit回调的onError方法中捕获它?