修改单例实例导致API调用中出现403问题?

时间:2017-12-05 03:04:02

标签: java retrofit retrofit2

我已经设置了一个由所有API方法访问的retrofit2单例实例。但是,在注销用户并重新登录后,所有API调用都会失败,并显示403.可能的原因是改造后重新使用以前销毁的访问令牌而不重置改造实例。

的Singleton:

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并不能解决问题。这个的重新解决方案是什么?

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。这是写的:

<强>问题:

  • 我需要全局访问改造实例,而不必每次都重新初始化实例

  • 问题中的代码将公共改造实例与经过身份验证的端点混淆,从​​而导致401:未经授权的错误。

<强>解决方案:

我在下面附上的解决方案是为了提供以下内容: - 使用Singleton设计模式重新使用改造实例

  • 能够编写接口APIServices并在其中包含所有端点。这允许可扩展性。

  • 能够在为公共端点构建的改造和为经过身份验证的端点构建的改造之间切换。

这是我的解决方案: https://gist.github.com/dinukapj/b315e5f4438bc670d7509f7aa7aaffdd