2015-11-10 19 views
6

Retrofit ve Dagger 2 kullanıyorum. Oeuth belirteci eklemek için bir OkHttp Interceptor uyguladım. Herhangi bir oauth jetonu olmadığı veya zaman damgasının geçersiz olduğu durumda, asıl talep gerçekleştirilmeden önce yenisini (Yükseltme servisi aracılığıyla) talep ediyorum.OkHttpClient bağımlılık döngüsü olmadan OkHttpClient kullanarak

Bu, Yükseltme hizmetinin Interceptor gerektirdiği bir bağımlılık döngüsü oluşturur, ancak Interceptor ayrıca Retrofit hizmetini de gerektirir (oauth belirtecini almak için). (Her zaman restService#refreshAccessToken aracılığıyla belirteci istekleri basitleştirme için) Interceptor için

Örnek:

@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()); 
} 

cevap

1

Sizin InterceptorInterceptor#intercept() yöntemde kendini enjekte etmek gerekecektir. Bu yolla, retrofit hizmetiniz (eklenen interceptor ile OkHttpClient dahil) bağımlılık döngüsü olmadan tatmin edilebilir.

Benim NetworkComponent (Benim Retrofit hizmetimi sağlar) benim Application sınıfında yaşıyor. İşte bir uygulama Context kullanarak enjekte etmenin bir örneği.

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()); 
    } 
} 

Ayrıca sadece muhtemelen daha iyi bir performans elde, tüm sınıf enjekte etmeden yerel bir değişken ayarlayabilirsiniz.

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

İlginç yaklaşımdır Tembel enjeksiyonu, tercih ederim. Her talep/kesişim bir enjeksiyona neden olduğu için bir dezavantajı var mı (ör. Performans)? Ayrıca Uygulama, bana biraz garip görünüyor NetworkComponent, ortaya çıkarmak zorunda. – Maradox

+0

Hançer 2 hızlı bir şekilde üretildi çünkü hızlı bir şekilde oluşturulmuş kod kullanıyor, bu yüzden aslında 'RestService'inizi kuran bazı yöntemleri çağırıyor. Bütün sınıfı cevaplarıma enjekte etmekten kaçınan alternatif bir yol ekledim. Bunu sağlayan 'Uygulama' olmak zorunda değil, uygulamanızın 'Tekton' bileşenlerini başka ne sağlayabilir? Uygulama çapındaki uygulamalarınızı Uygulamada saklamak, okuduğum tüm Hançer 2 şeylerinde yaygın bir uygulamadır. –

0

Ben şahsen biraz daha temiz

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

Vay, bu çok temiz! Bunun hala bir '@ject 'ek açıklamalarına ihtiyacı var mı? –

+0

Bu size bağlı. Hayır, sağlayıcı yazarsak –

İlgili konular