Android凌空处理重定向

Nik*_*iko 27 android android-volley

我最近开始使用谷歌的Volley lib来处理我的网络请求.我的一个请求获得错误301重定向,所以我的问题是,可以自动地以某种方式自动处理重定向,还是我必须手动处理parseNetworkError或使用某种在RetryPolicy这里?

谢谢.

Muc*_*hit 37

将url.replace替换为url("http","https");

例如:如果你的网址看起来像那样:" http://graph.facebook ......."应该是这样:" https://graph.facebook ......."

这个对我有用


Nik*_*iko 21

我修复了它捕获http状态301或302,读取重定向网址并将其设置为请求然后投掷预期触发重试.

编辑:以下是我修改的volley lib中的主键:

  • setUrl(final String url)为类添加方法public voidRequest

  • 在类BasicNetwork中添加了检查重定向//处理缓存验证后if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY) || statusCode == HttpStatus.SC_MOVED_TEMPORARILY),在那里我读了重定向url responseHeaders.get("location"),调用setUrl请求对象并抛出错误

  • 错误得到了捕获并且它调用了 attemptRetryOnException

  • 您还需要RetryPolicy设置Request(参见DefaultRetryPolicy此内容)

  • 请参阅https://github.com/samkirton/android-volley获取带有重定向修复的齐射分叉. (5认同)
  • 您的回答不明确,能否解释一下 (4认同)

slo*_*ott 13

如果你不想修改Volley lib,你可以捕获301并手动重新发送请求.

在您的GsonRequest类中,实现deliverError并使用标头中的新Location url创建一个新的Request对象,并将其插入请求队列.

像这样的东西:

@Override
public void deliverError(final VolleyError error) {
    Log.d(TAG, "deliverError");

    final int status = error.networkResponse.statusCode;
    // Handle 30x 
    if(HttpURLConnection.HTTP_MOVED_PERM == status || status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_SEE_OTHER) {
        final String location = error.networkResponse.headers.get("Location");
        Log.d(TAG, "Location: " + location);
        final GsonRequest<T> request = new GsonRequest<T>(method, location, jsonRequest, this.requestContentType, this.clazz, this.ttl, this.listener, this.errorListener);
        // Construct a request clone and change the url to redirect location.
        RequestManager.getRequestQueue().add(request);
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以不断更新Volley,而不必担心破坏事件.


yuv*_*val 6

像许多其他人一样,我只是对为什么Volley没有自动跟踪重定向感到困惑.通过查看源代码,我发现虽然Volley会自己正确设置重定向URL,但除非请求的重试策略指定"重试"至少一次,否则它实际上不会遵循它.令人费解的是,默认重试策略设置maxNumRetries为0.因此,修复方法是设置重试策略,重试次数为1次(10次超时,默认情况下复制1次后退):

request.setRetryPolicy(new DefaultRetryPolicy(10000, 1, 1.0f))
Run Code Online (Sandbox Code Playgroud)

供参考,这是源代码:

/**
 * Constructs a new retry policy.
 * @param initialTimeoutMs The initial timeout for the policy.
 * @param maxNumRetries The maximum number of retries.
 * @param backoffMultiplier Backoff multiplier for the policy.
 */
public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {
    mCurrentTimeoutMs = initialTimeoutMs;
    mMaxNumRetries = maxNumRetries;
    mBackoffMultiplier = backoffMultiplier;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建RetryPolicy仅在301或302的情况下"重试" 的自定义实现.

希望这有助于某人!


Rub*_*one 5

最终合并了大多数 @niko 和 @slott 的回答:

// Request impl class
// ...

    @Override
    public void deliverError(VolleyError error) {
        super.deliverError(error);

        Log.e(TAG, error.getMessage(), error);

        final int status = error.networkResponse.statusCode;
        // Handle 30x
        if (status == HttpURLConnection.HTTP_MOVED_PERM ||
                status == HttpURLConnection.HTTP_MOVED_TEMP ||
                status == HttpURLConnection.HTTP_SEE_OTHER) {
            final String location = error.networkResponse.headers.get("Location");
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "Location: " + location);
            }
            // TODO: create new request with new location
            // TODO: enqueue new request
        }
    }

    @Override
    public String getUrl() {
        String url = super.getUrl();

        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            url = "http://" + url; // use http by default
        }

        return url;
    }
Run Code Online (Sandbox Code Playgroud)

它很好地覆盖了StringRequest方法。

希望它可以帮助别人。