Android凌空处理redirect

我最近开始使用Google的Volley lib来处理我的networking请求。 我的一个请求得到错误301redirect,所以我的问题是,可以自动处理redirect不知何故自动或我必须在parseNetworkError手动处理它或在这里使用某种RetryPolicy

谢谢。

Solutions Collecting From Web of "Android凌空处理redirect"

replace你的url,就像那个url.replace(“http”,“https”);

例如:如果你的url看起来像:“ http://graph.facebook …….”比它应该是这样的:“ https://graph.facebook …….”

这个对我有用

我修正它捕捉http状态301或302,读取redirecturl并将其设置为请求,然后抛出期望触发重试。

编辑:这是我修改的排球库中的主键:

  • 为类Request添加了方法public void setUrl(final String url)

  • 在类BasicNetwork中,//在处理cachingvalidation之后,添加了redirect检查if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY) || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY) || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ,那里我读了responseHeaders.get("location")的redirecturl,用请求对象调用setUrl并抛出错误

  • 遇到错误,它调用了attemptRetryOnException

  • 您还需要为Request设置RetryPolicy (请参阅DefaultRetryPolicy

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

在您的GsonRequest类中实现deliverError,并使用头中新的Location url创build一个新的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); } } 

这样你可以不断更新Volley,而不用担心事情的中断。

和其他许多人一样,我对于Volley为什么不自动追踪redirect感到困惑。 通过查看源代码,我发现虽然Volley将自行正确设置redirectURL,但除非请求的重试策略指定至less“重试”一次,否则不会实际遵循redirectURL。 maxNumRetries是,默认重试策略将maxNumRetries设置为0.因此,修复方法是设置重试策略,重试次数为1(从默认情况下复制10s超时和1x退格):

 request.setRetryPolicy(new DefaultRetryPolicy(10000, 1, 1.0f)) 

作为参考,这里是源代码:

 /** * 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; } 

或者,您可以创buildRetryPolicy的自定义实现,只有在301或302的情况下才会“重试”。

希望这可以帮助别人!

Volley支持没有任何补丁的redirect,不需要单独的分支

说明:排除内部使用HttpClient ,默认情况下遵循301/302,除非另有规定

来自: http : //hc.apache.org/httpcomponents-client-4.2.x/tutorial/html/httpagent.html

ClientPNames.HANDLE_REDIRECTS ='http.protocol.handle-redirects':定义是否应该自动处理redirect。 这个参数需要一个java.lang.Booleantypes的值。 如果这个参数没有设置,HttpClient会自动处理redirect。

好吧,我有点迟到这里的游戏,但我最近一直试图达到这个相同的方面,所以https://stackoverflow.com/a/17483037/2423312是最好的,因为你愿意叉凌空抽搐,并维护它和答案在这里&#xFF1A; https ://stackoverflow.com/a/27566737/2423312 – 我不知道这是如何工作。这一点虽然是现货: https ://stackoverflow.com/a/ 28454312/2423312 。 但是它实际上添加了一个新的请求对象到NetworkDipatcher的队列中,所以你必须以某种方式通知调用者,这里有一个肮脏的方法 ,你可以通过不修改请求对象+改变字段“mURL “,请注意,这取决于您执行sorting的RetryPolicy.java接口,以及您的类如何扩展Request.java类,在这里你去: welcome REFLECTION

 Class volleyRequestClass = request.getClass().getSuperclass(); Field urlField = volleyRequestClass.getDeclaredField("mUrl"); urlField.setAccessible(true); urlField.set(request, newRedirectURL); 

就个人而言,我宁愿克隆排列 。 加上看起来像凌云的例子BasicNetwork类被devise为在redirect失败: https : //github.com/google/volley/blob/ddfb86659df59e72​​93df9277da216d73c34aa800/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java#L156所以我猜他们没有太多的redirect,随意build议/编辑。 一直在寻找好的方式..

最终做最@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; } 

它很好地覆盖了StringRequest方法。

希望它可以帮助任何人。