2017-12-05 15 views
0

私はすべてのAPIメソッドによってアクセスされるretrofit2シングルトンインスタンスをセットアップしました。ただし、ユーザーをログアウトして再サインインすると、すべてのAPI呼び出しが403で失敗します。これは、以前に破棄されたアクセストークンを再利用して、再構築されたインスタンスをリセットしないようにするためです。API呼び出しで403の問題を引き起こす改造シングルトンインスタンス?

シングルトン:

public class RetroGenerator { 

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); 
    private static Retrofit.Builder builder; 
    public static Retrofit retrofit; 

    static synchronized private Retrofit.Builder getBuilder() { 

     if (builder == null) { 
      initRetrofit(); 
     } 
     return builder; 
    } 

    public static void initRetrofit() { 
     builder = 
       new Retrofit.Builder() 
         .baseUrl(SessionManager.getInstance().baseUrl) 
         .addConverterFactory(GsonConverterFactory.create(initGson())); 
    } 

    private static Gson initGson() { 
     return new GsonBuilder() 
       .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create(); 
    } 

    public static Retrofit getRetrofit() { 
     return getBuilder().client(httpClient.build()).build(); 
    } 

    public static <S> S createService(Class<S> serviceClass) { 
     return getRetrofit().create(serviceClass); 
    } 

    public static <S> S createService(Class<S> serviceClass, final Auth auth) { 
     if (retrofit == null) { 
      if (auth != null) { 

       //Adding request payload logging 
       if (BuildConfig.DEBUG) { 
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); 
        logging.setLevel(HttpLoggingInterceptor.Level.BODY); 
        httpClient.addInterceptor(logging); 
       } 

       httpClient.retryOnConnectionFailure(true); 
       httpClient.addInterceptor(new Interceptor() { 
        @Override 
        public Response intercept(Interceptor.Chain chain) throws IOException { 
         Request original = chain.request(); 
         Request.Builder requestBuilder = original.newBuilder() 
           .header("Accept", "application/json") 
           .header("Authorization", 
             auth.token_type + " " + auth.access_token) 
           .method(original.method(), original.body()); 
         Request request = requestBuilder.build(); 
         return chain.proceed(request); 
        } 
       }); 
      } 

      OkHttpClient client = httpClient.build(); 

      if (retrofit == null) { 
       retrofit = getBuilder().client(client).build(); 
      } 
     } 

     return retrofit.create(serviceClass); 
    } 

    public static void clearRetrofit(){ 
     retrofit = null; 
    } 
} 

APIクラスがすることで、これを使用します。これを修正するには

RetroGenerator.createService(APIServices.class).getUsers().enqueue(new Callback<ArrayList<User>>() { 
    @Override 
    public void onResponse(Call <ArrayList<User>> call, Response <ArrayList<User>> response) { 
     if (response.isSuccessful()) { 
      callBack.onSuccess(response.body()); 
     } 
    } 
    @Override 
    public void onFailure(Call <ArrayList<User>> call, Throwable t) { 

    } 
}); 

、私の試みは、サインアウト時にNULLとして改造インスタンスを設定することでした。従って、clearRetrofit()方法の使用。しかし、問題はまだ存在し、それをヌルに設定しても問題は解決しませんでした。これの根本原因は何ですか?

答えて

0

私はこの問題を解決しました。ここでは、ライトアップです:

問題:私はインスタンスに問題のコードだったたび

  • を再初期化することなく、改造インスタンスへのグローバルアクセスを必要と

    • 公開された更新インスタンスを認証されたエンドポイントと混同し、401:Unauthorizedエラーにつながります。

    ソリューション:

    私が書かれた下に添付しましたソリューションが提供する以下: - 再利用性改造インスタンスのシングルトンデザインパターン

    • を使用して

      インターフェイスAPIServicesを作成し、その中にすべてのエンドポイントを含めることができます。これにより、拡張性が可能になります。

    • パブリックエンドポイント用に構築されたレトロフィットと、認証済みエンドポイント向けに構築されたレトロフィットを切り替えることができます。ここで

    は私のソリューションです: https://gist.github.com/dinukapj/b315e5f4438bc670d7509f7aa7aaffdd

  • 関連する問題