I'm using Retrofit and Dagger 2. I have implemented an OkHttp Interceptor
for adding the oauth token. In the case there is no oauth token or the timestamp is invalid, I request a new one (via the Retrofit service) before the actual request is carried out.
This creates a dependency cycle where the Retrofit service requires the Interceptor
but the Interceptor
also requires the Retrofit service (for retrieving the oauth token).
Example for the Interceptor
(for simplification it always requests the token via restService#refreshAccessToken
):
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder requestBuilder = originalRequest.newBuilder();
String authHeader = "Bearer " + restService.refreshAccessToken();
requestBuilder.addHeader("Authorization", authHeader);
return chain.proceed(requestBuilder.build());
}
Your Interceptor
will need to inject itself in the Interceptor#intercept()
method. This way your Retrofit service (including the OkHttpClient
with the added interceptor) dependency can be satisfied without a dependency cycle.
My NetworkComponent
(which provides my Retrofit service) lives in my Application
class. Here is an example of injecting it using an Application Context
.
public class AuthInterceptor implements Interceptor {
@Inject RestService restService;
public AuthInterceptor(Context context) {
mContext = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
// Inject Retrofit service
((MyApplication) context.getApplicationContext())
.getNetworkComponent().inject(this);
Request originalRequest = chain.request();
Request.Builder requestBuilder = originalRequest.newBuilder();
String authHeader = "Bearer " + restService.refreshAccessToken();
requestBuilder.addHeader("Authorization", authHeader);
return chain.proceed(requestBuilder.build());
}
}
You could also just set a local variable without injecting the entire class, possibly getting better performance.
RestService restService = InjectHelper.getNetworkComponent(mContext).restService();
I personally prefer Lazy injection, which is a bit cleaner
public class AuthInterceptor implements Interceptor {
Lazy<RestService> restService;
@Inject
public AuthInterceptor(Lazy<RestService> restService) {
this.restService = restService;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder requestBuilder = originalRequest.newBuilder();
String authHeader = "Bearer " + restService.get().refreshAccessToken();
requestBuilder.addHeader("Authorization", authHeader);
return chain.proceed(requestBuilder.build());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With