java - 改造界面的设计模式

标签 java android design-patterns retrofit

我的 Retrofit 界面创建器的设计有问题。我希望能够以通用方式实例化 API 接口(interface),并在传递 token 时更新相应的实例。目前,当我更新 token 时,我必须再次调用 createService() 方法以获取在接口(interface)生成中使用 token 的新实例...

有人问过类似的问题,但从未得到答案 here

public class RetrofitCreator {

    private static String TAG = "RetrofitCreator";
    private static String WSSE = null;
    private static String AmzToken = null;
    static HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    private static AmazonAPI amazonAPI = null;
    private static VanishAPI cobaltAPI = null;

    //static OkHttpClient client = new OkHttpClient.Builder().build();
    static OkHttpClient.Builder httpClient = new OkHttpClient.Builder().addInterceptor(interceptor.setLevel(HttpLoggingInterceptor.Level.BODY));

    private static Retrofit.Builder builder =
            new Retrofit.Builder();

    public static <S> S createService(Class<S> serviceClass) {

        S mAPI = null;
            if(serviceClass.getSimpleName().equals("VanishAPI")){
                if(VanishAPI==null){
                    VanishAPI = (VanishAPI) createVanishAPI(serviceClass);
                }
                mAPI = (S) VanishAPI;
            }else if(serviceClass.getSimpleName().equals("AmazonAPI")){
                if(amazonAPI==null){
                    amazonAPI = (AmazonAPI) createAmazonAPI(serviceClass);
                }
                mAPI = (S) amazonAPI;
            }
        return mAPI;
    }


    public static void setWSSE(String WSSE) {
        RetrofitCreator.WSSE = WSSE;
        vanishAPI = createVanishAPI(VanishAPI.class);
    }

    public static void setAmzToken(String token) {
        RetrofitCreator.AmzToken = token;
        amazonAPI = createAmazonAPI(AmazonAPI.class);
    }

private static <S> S createAmazonAPI(Class<S> serviceClass){
    httpClient = getUnsafeOkHttpClient();
    builder = new Retrofit.Builder()
            .baseUrl(Constants.URL_AMAZON)
            .addConverterFactory(JacksonConverterFactory.create());

    if (AmzToken != null) {
        Log.w(TAG, "WSSE not null!");
        Interceptor interceptorSecure = new Interceptor() {
            @Override
            public Response intercept(Interceptor.Chain chain) throws IOException {
                Request original = chain.request();

                // Request customization: add request headers
                Request.Builder requestBuilder = original.newBuilder()
                        .header("Cache-Control", "no-cache")
                        .header("Accept", "application/json")
                        .header("Authorization", "Bearer " + AmzToken)
                        .method(original.method(), original.body());

                Request request = requestBuilder.build();
                return chain.proceed(request);
            }
        };
        httpClient.addInterceptor(interceptorSecure);
    }

    OkHttpClient client = httpClient.build();
    Retrofit retrofit = builder.client(client).build();
    return retrofit.create(serviceClass);
}

(...)
}

要在我使用的每个 Activity 中获取它:

amazonApi = RetrofitCreator.createService(AmazonAPI.class);

最佳答案

让你的拦截器看起来像这样:

public class TokenInterceptor implements Interceptor {

    private String token;

    public String getToken() {
        return token;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();

            // Request customization: add request headers
            Request.Builder requestBuilder = original.newBuilder()
                    .header("Cache-Control", "no-cache")
                    .header("Accept", "application/json")
                    .method(original.method(), original.body());
            if (getToken() != null) {
                requestBuilder.header("Authorization", "Bearer " + AmzToken);
            }
            Request request = requestBuilder.build();
            return chain.proceed(request);
    }

    public void setToken(String token) {
        this.token = token;
    }
}

将其添加到您的 OkHttp 客户端并保留对该拦截器的引用。 现在您不必在每次 token 更改后调用 createService()。只需通过 interceptor.setToken()

更改拦截器中的 token

关于java - 改造界面的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36337259/

相关文章:

android - Android 开发者的 printf 等价物?

android - 如何在 Espresso Test Android Studio 的软键盘模拟器上按下 "search button"

android - 在APK META-INF/maven/com.nineoldandroids/library/pom.xml中复制的重复文件

oop - 为什么助手类是反模式

java - hibernate 无PK

java - 类设计问题【可选实现】

java - 找不到 JAVA_HOME Linux Mint : Trying to use Cordova to build an Android App

java - 为什么 Future isDone() 会像 Future get() 一样阻塞程序?

c - 算法与设计模式有何不同?

javascript - 当前项目告诉我需要查看 Javascript OOP,我应该吗?