我有一个基于令牌的Api身份验证(Laravel Passport)的工作代码示例,但它没有Dagger 2.我想将代码从当前RetrofitBuilder.java
移动到AppModule,这样我就可以使用Dagger的强大功能2在应用程序中。
对于Now,没有Dagger Dependency,我在RetrofitBuilder.java
中有两个静态方法,可用于经过身份验证的路由调用和未经身份验证的路由调用:
1) createService(service)
//哪个API调用没有授权标头(没有访问令牌)
2) createServiceWithAuth(service, tokenManager)
//使用授权标头进行API调用,例如使用访问令牌
如何使用Dagger依赖实现相同的功能。我如何才能将上述两种方法提供给我的业务逻辑类,例如UserRepository.java
,以便我可以在任何必要的地方进行经过身份验证和未经身份验证的服务调用。
RetrofitBuilder.java
public class RetrofitBuilder {
private static final String BASE_URL = "https://api.com/";
private final static OkHttpClient client = buildClient();
private final static Retrofit retrofit = buildRetrofit(client);
private static OkHttpClient buildClient(){
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Connection", "close");
request = builder.build();
return chain.proceed(request);
}
});
if(BuildConfig.DEBUG){
builder.addNetworkInterceptor(new StethoInterceptor());
}
return builder.build();
}
private static Retrofit buildRetrofit(OkHttpClient client){
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(MoshiConverterFactory.create())
.build();
}
public static <T> T createService(Class<T> service){
return retrofit.create(service);
}
public static <T> T createServiceWithAuth(Class<T> service, final TokenManager tokenManager){
OkHttpClient newClient = client.newBuilder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
if(tokenManager.getToken().getAccessToken() != null){
builder.addHeader("Authorization", "Bearer " + tokenManager.getToken().getAccessToken());
}
request = builder.build();
return chain.proceed(request);
}
}).authenticator(CustomAuthenticator.getInstance(tokenManager)).build();
Retrofit newRetrofit = retrofit.newBuilder().client(newClient).build();
return newRetrofit.create(service);
}
public static Retrofit getRetrofit() {
return retrofit;
}
}
CustomAuthenticator.java (如果访问令牌已过期,则刷新令牌)
public class CustomAuthenticator implements Authenticator {
private TokenManager tokenManager;
private static CustomAuthenticator INSTANCE;
private CustomAuthenticator(TokenManager tokenManager){
this.tokenManager = tokenManager;
}
static synchronized CustomAuthenticator getInstance(TokenManager tokenManager){
if(INSTANCE == null){
INSTANCE = new CustomAuthenticator(tokenManager);
}
return INSTANCE;
}
@Nullable
@Override
public Request authenticate(Route route, Response response) throws IOException {
if(responseCount(response) >= 3){
return null;
}
AccessToken token = tokenManager.getToken();
ApiService service = RetrofitBuilder.createService(ApiService.class);
Call<AccessToken> call = service.refresh(token.getRefreshToken() + "a");
retrofit2.Response<AccessToken> res = call.execute();
if(res.isSuccessful()){
AccessToken newToken = res.body();
tokenManager.saveToken(newToken);
return response.request().newBuilder().header("Authorization", "Bearer " + res.body().getAccessToken()).build();
}else{
return null;
}
}
private int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
}
的 AppModule.java
@Module(includes = ViewModelModule.class)
public class AppModule {
// --- DATABASE INJECTION ---
@Provides
@Singleton
MyDatabase provideDatabase(Application application) {
return Room.databaseBuilder(application,
MyDatabase.class, "MyDatabase.db")
.build();
}
@Provides
@Singleton
UserDao provideUserDao(MyDatabase database) { return database.userDao(); }
// --- REPOSITORY INJECTION ---
@Provides
Executor provideExecutor() {
return Executors.newSingleThreadExecutor();
}
@Provides
@Singleton
UserRepository provideUserRepository(UserWebservice webservice, UserDao userDao, Executor executor) {
return new UserRepository(webservice, userDao, executor);
}
// --- NETWORK INJECTION ---
private static String BASE_URL = "https://api.com/";
@Provides
Gson provideGson() { return new GsonBuilder().create(); }
@Provides
Retrofit provideRetrofit(Gson gson) {
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl(BASE_URL)
.build();
return retrofit;
}
@Provides
@Singleton
UserWebservice provideApiWebservice(Retrofit restAdapter) {
return restAdapter.create(UserWebservice.class);
}
}
答案 0 :(得分:1)
您可以将okHttp和retrofit的创建移动到Dagger模块,然后将其分配给您需要的服务构造函数。
代码如下:
@Module
public class ServiceModule {
@Provides
@Singleton
OkHttp provideOkHttp(Authenticator authenticator) {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Connection", "close");
request = builder.build();
return chain.proceed(request);
}
});
if (BuildConfig.DEBUG) {
builder.addNetworkInterceptor(new StethoInterceptor());
}
// build this authenticator in the same way as all the other dependencies shown here
builder.authenticator(authenticator);
return builder.build();
}
@Provides
@Singleton
Retrofit provideRetrofit(OkHttp okHttp) {
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttp)
.addConverterFactory(MoshiConverterFactory.create())
.build();
}
@Provides
@Singleton
Service provideService(Retrofit retrofit) {
return new ServiceImpl(retrofit);
}
}
代码未经过测试......