我们有没有可能在 OkHttp 拦截器中停止请求?

问题描述 投票:0回答:3

在我们的应用程序中,我们遇到了一个特殊情况 - 如果我们的

App.specialFlag == true
,我们需要停止来自我们代码的任何请求。我们认为,在这种情况下最好的方法是包含特殊的
Interceptor
,这将停止我们的任何请求,像这样:

if (App.specialFlag) {
    // Somehow stop request
} else {
    return chain.proceed(chain.request());
}

此外,我们应该注意,我们使用

RxJavaCallAdapterFactory
将响应包装到
Observable
s 中。

但是我们在 OkHttp 拦截器中没有看到任何停止请求的方法。

我们想出了两种方法来解决我们的问题:

a) 创建特殊的

ApiService.class
来包装我们 API 中的每个请求,如下所示:

public Observable<User> getUserDetails() {
    if (App.specialFlag) {
        return Observable.just(null);
    }
    return api.getUserDetails();
}

但我们认为这是丑陋和麻烦的解决方案。

b) 在 Interceptor 中抛出一个

RuntimeException
,然后在我们使用 API 的每个地方捕获它。

第二个解决方案也不好,因为我们需要在我们的链中包含很多

onErrorResumeNext
运营商。

可能有人知道,如何以更“聪明”的方式处理我们的情况?..

提前致谢!

android retrofit rx-java okhttp
3个回答
37
投票

接受的答案中缺少的一件事是您需要指定协议和消息。如果您不指定,您将获得异常。看起来像这样:

if (App.specialFlag) {
    return new Response.Builder()
                       .code(418) // Whatever code
                       .body("".toResponseBody(null)) // Whatever body
                       .protocol(Protocol.HTTP_2)
                       .message("Dummy response")
                       .request(chain.request())
                       .build();
} else {
    return chain.proceed(chain.request());
}

29
投票

防止请求被执行(在它开始之前)的一种方法是简单地按照您尝试的方式执行,但添加了Response.Builder

if (App.specialFlag) {
    return new Response.Builder()
                       .code(600) //Simply put whatever value you want to designate to aborted request.
                       .protocol(Protocol.HTTP_2)
                       .message("Dummy response")
                       .request(chain.request())
                       .build();
} else {
    return chain.proceed(chain.request());
}

编辑 26/09/2019 更新了答案,其中包含 Bobstring

提到的详细信息

-2
投票
  1. 我建议将控制逻辑脚本放在 OkHttp 之外,因为它仅用于发出 http 请求。如何触发请求,如何处理响应来更新UI,不需要关心;

  2. 如果你愿意,你可以创建一个继承自okhttp3.Interceptor的Class,然后覆盖函数拦截并将你的控制逻辑脚本放在里面。

    OkHttpClient client = new OkHttpClient.Builder()
       .connectTimeout(20, TimeUnit.SECONDS)
       .readTimeout(20, TimeUnit.SECONDS)
       .addInterceptor(new Interceptor())
       .build();
    
© www.soinside.com 2019 - 2024. All rights reserved.