OkHttp interceptor using OkHttpClient without dependency loop

I use Retrofit and Dagger 2. I added OkHttp Interceptor to add oauth token. In case there is no oauth token or the timestamp is invalid, I request a new one (through the Retrofit service) before the actual request is made.

This creates a dependency loop in which the Retrofit service requires an Interceptor , but the Interceptor also requires the Retrofit service (to get the oauth token).

Example for Interceptor (for simplicity, it always requests a token through 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()); } 
+6
source share
2 answers

Your Interceptor will need to introduce itself into the Interceptor#intercept() method. This way your Retrofit service (including the OkHttpClient dependency with an added sniffer) can be satisfied without a dependency loop.

My NetworkComponent (which provides my Retrofit service) lives in my Application class. The following is an example of entering it using the Context application.

 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 can also just set a local variable without entering the whole class, perhaps getting better performance.

 RestService restService = InjectHelper.getNetworkComponent(mContext).restService(); 
+1
source

I personally prefer a lazy injection that is a little clean

 public class AuthInterceptor implements Interceptor { Lazy<RestService> restService; 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()); } } 
0
source

All Articles