2017-12-05 9 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() 방법의 사용. 그러나 문제는 여전히 존재하며 null로 설정해도 문제가 해결되지 않았습니다. 이것에 대한 진정한 해결책은 무엇입니까?

답변

0

이 문제가 해결되었습니다. 여기에 쓰기까지입니다 :

문제 : 인스턴스에게 문제의 코드가 될 때마다

  • 를 다시 초기화 할 필요없이 개조 인스턴스에 대한 글로벌 액세스를 필요로

    • 공개 된 갱신 인스턴스를 인증 된 엔드 포인트와 혼동하여 401 : Unauthorized 오류가 발생합니다.

    솔루션 :

    내가 쓴 아래에 첨부했습니다 솔루션을 제공 할 수있는 다음 - 재사용 성 개조 인스턴스의 단일 디자인 패턴

    • 를 사용하여

      APIServices 인터페이스를 작성하고 그 안에 모든 엔드 포인트를 포함 할 수 있습니다. 이것은 확장 성을 허용합니다.

    • 공개 엔드 포인트 용으로 개조 된 개조와 인증 된 엔드 포인트 용으로 개조 된 개조를 전환 할 수있는 기능. https://gist.github.com/dinukapj/b315e5f4438bc670d7509f7aa7aaffdd

      : 여기

    내 솔루션입니다