如何检测 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。
我自己的测试表明这是有效的,例如
$ 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
}
使用 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。
我自己的测试表明这是有效的,例如
$ 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
}