我想在authorization
中使用Retrofit2
。我选择interceptor
的方式是因为几乎所有方法都需要authorization
,除了我要获取令牌以供其他方法进一步使用的一种方法。
我的问题是:我该如何实现?
我将访问令牌存储在SharedPreferences
中。我的第一个想法是:“ 我可以在我的RetrofitClient
类中检索它,并根据令牌是否为null或是否具有值来创建合适的Retrofit
实例”(添加或不添加{ {1}}。
不幸的是,这并不容易,因为需要.client()
才能获得偏好。
我不知道如何将其传递给Context
类或如何将其传递给内部。
这是我的RetrofitClient
班:
RetrofitClient
我的public class RetrofitClient {
public static final String BASE_URL = "http://localhost";
public static Retrofit retrofit = null;
private RetrofitClient() {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
//.client(getRequestHeader())
.build();
}
/*OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer" + )
}
})*/
public static synchronized Retrofit getInstance() {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
public Api getApi() {
return retrofit.create(Api.class);
}
}
是我设置超时的先前方法。
我想创建这样的实例:
getRequestHeader()
然后:
private RetrofitClient() {
tokenService.token = null;
tokenService.readToken(ApplicationContext.getInstance());
if (tokenService.token == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
} else {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client) //I have interceptor here with access token
.build();
}
}
//获取令牌
RetrofitClient.getInstance().create(Api.class).getToken()
//当我获得令牌时
这是好方法吗?
答案 0 :(得分:1)
您可以使用应用程序处于活动状态时可用的应用程序上下文。从您的应用程序类中获取它:
public class MyApp extends Application {
private static MyApp instance;
@Override
public void onCreate() {
super.onCreate();
instance = this;
//other code
}
public static MyApp getInstance() {
return instance;
}
然后只需使用MyApp.getInstance()
即可在需要的地方获取上下文。使用这种方法,您可以实现之前的想法,并在RetrofitClient
类中获得SharedPreferences。
别忘了添加您的应用程序类以进行显示。
更新: 您只创建一次改造实例,因此,如果您在拥有令牌时创建它-您将始终在应用程序运行时使用它。 我认为,好的做法是在拦截器中检查令牌。像这样:
new Interceptor() {
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request();
if (tokenService.token == null) {
return chain.proceed(request);
} else {
return chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer" + tokenService.token).build());
}
}
}
此外,我不知道您的tokenService的工作方式。但是请记住,最好的办法是始终签入令牌的共享首选项,如果您在注销时在此清除令牌。因为即使在共享首选项中将其清除,您的tokenService仍可能保留令牌字符串。
答案 1 :(得分:0)
只需根据情况将SharedPreferences添加为RetrofitClient或其他中的构造函数参数
答案 2 :(得分:0)
您可以通过以下方式进行操作:
首先使用单例实例创建一个首选项类
首选项
public class Preferences {
public static Preferences INSTANCE;
private final String PREFERENCE_FILE = "my_preferences";
public final String PREF_TOKEN = "pref_user_token";
private SharedPreferences mPrefs;
private SharedPreferences.Editor mEdit;
private Preferences() {
Application app = MyApplicationClass.getInstance();
mPrefs = app.getSharedPreferences(PREFERENCE_FILE, Context.MODE_PRIVATE);
mEdit = mPrefs.edit();
}
// Returns singleton instance
public static Preferences getInstance() {
if (INSTANCE == null)
INSTANCE = new Preferences();
return INSTANCE;
}
public String getToken() {
return Preferences.getInstance().mPrefs.getString(PREF_TOKEN, "");
}
public void saveToken(String value) {
mEdit.putString(PREF_TOKEN, value);
mEdit.apply();
}
}
然后在RetrofitClient类中进行如下更改:
RetrofitClient
public class RetrofitClient {
public static final String BASE_URL = "http://localhost";
public static Retrofit retrofit = null;
private RetrofitClient() {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(mClient)
.build();
}
OkHttpClient mClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer" + Preferences.getInstance().getToken())
}
})
public static synchronized Retrofit getInstance() {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
public Api getApi() {
return retrofit.create(Api.class);
}
}