如何检测 Glide v4 / OkHttp3 中的重定向?

How to detect a redirection in Glide v4 / OkHttp3?

使用 Glide v4 和 OkHttp3,如何检测重定向并在重定向发生时加载另一个 url?

我的用例:我使用带有 OkHttp3 的 Glide v4 库在我的应用程序中下载图片。有时当图片不可用时,服务器会执行重定向以提供另一张图片而不是我最初想要的图片。我可以在我的浏览器中看到它,因为当我请求 url A 时,我终于用第二张图片登陆了 url B。当发生这种情况时,我想改为加载从 url A 派生的 url C(因此不是静态的 url)。

目前我可以使用 OkHttp3 拦截器检测重定向:

public Response intercept(@NonNull Chain chain) throws IOException {
    String requestUrl = chain.request().url().toString();
    Response response = chain.proceed(chain.request());
    String responseUrl = response.request().url().toString();

    boolean redirect = !requestUrl.equals(responseUrl);
    if (redirect) {
        Timber.d("Detected redirection");
    }

    return response;
}

但是我不知道如何干净地加载 url C。我不知道如何在拦截器中加载另一个 url,如果我抛出一个 IOException 来处理稍后在 Glide RequestListener 中的错误只会导致 GlideException,所以我无法确定它被抛出的原因。

OkHttp 应该默认自动重定向并加载最终内容。参见 OkHttpClient.Builder.followRedirects。

https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.Builder.html#followRedirects-boolean-

我自己的测试表明这是有效的,例如

$ oksocial 'https://httpbin.org/redirect-to?url=https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg'

为了检测它,我假设您的拦截器是通过 addInterceptor 而不是 addNetworkInterceptor 注册的。对吗?

同样值得确保重定向是通过 30X 响应而不是通过 HTML 刷新。

我最终得到的解决方案非常丑陋:我在问题中展示的请求拦截器在检测到重定向时引发 IOException。然后我将使用 GlideListener 来检测错误,并加载 url C。丑陋的部分是在 GlideListener 中我无法确定错误的原因,它可以是重定向但也可以是网络错误或其他任何问题。

使用自定义 OkHttpUrlLoader 可能可以实现此解决方案的更简洁版本,但对于我的简单用例来说代码太多了。

这是我在 Glide v4 / OkHttp3 中的解决方案

String redirect = response.header("location");
if(redirect != null && !request.url().toString().equals(redirect)) {
    // if redirected your code here
}