AsyncHttpClient 中的重定向和 setEnableRedirects 方法異常解決
今天使用 AsyncHttpClient 開源庫,遇到個很崩潰的問題:
方法 setEnableRedirects(false); 從名稱上看應該是重定向開關的方法,設置為 false 後則普通請求正常,但是遇到重定向則停止請求,還算正常(文章末尾會談到這裏會遇到另一個 BUG 的情況)
但當設置為 setEnableRedirects(true); 按理說應該是對於 301、302 重定向將進行跟隨重定向進行請求的,但卻出現各種異常和亂七八糟的問題,不論是普通請求還是重定向的請求全是 ClientProtocolException、 CircularRedirectException 等異常,有時還不停的 GC
類似:
各種調試,弄了大半天才終於搞定是怎麼回事!
我覺得 AsyncHttpClient 開源庫中的源碼 setEnableRedirects 方法有問題,看了下源碼:
/** * Simple interface method, to enable or disable redirects. If you set manually RedirectHandler * on underlying HttpClient, effects of this method will be canceled. * * @param enableRedirects boolean */ public void setEnableRedirects(final boolean enableRedirects) { httpClient.setRedirectHandler(new DefaultRedirectHandler() { @Override public boolean isRedirectRequested(HttpResponse response, HttpContext context) { return enableRedirects; } }); }
似乎設置為 setEnableRedirects 為 true 後,所有請求包括 http 200 都會 isRedirectRequested 方法都會返回 true 標記為重定向導致所有請求全部都出現問題,
於是新建個類繼承 AsyncHttpClient 後重寫了他的 setEnableRedirects 方法,隻對 301和 302進行重定向返回設置的 boolean 值,這下測試就 ok 了,普通請求正常,重定向則自動重定向請求到數據了,跟預想的結果一樣了:
修改後的代碼:
@Override public void setEnableRedirects(final boolean enableRedirects) { ((DefaultHttpClient) getHttpClient()).setRedirectHandler(new DefaultRedirectHandler() { @Override public boolean isRedirectRequested(HttpResponse response, HttpContext context) { int statusCode = response.getStatusLine().getStatusCode(); ZLog.i("setEnableRedirects", "code:"+ statusCode); if (statusCode == 301 || statusCode == 302) { ZLog.i("setEnableRedirects", "enableRedirects: true"); return enableRedirects; } return false; } }); }
這樣當 設置為 false 時則全部狀態都返回 false,設置為true 時則僅對 301、302 才返回 true,其餘都返回 false
同時還要配置下麵的參數設置:
getHttpClient().getParams().setParameter(ClientPNames.MAX_REDIRECTS, 3); getHttpClient().getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
允許環形重定向和設置重定向最大次數。
AsyncHttpClient 中的重定向和 setEnableRedirects 方法異常解決
下麵還有個重要提示:
經過我多次的測試實驗,發現:
其實係統默認應該是允許請求重定向的,但這裏有個 BUG,就是如果你有兩個請求是相同的鏈接地址,則隻有第一個請求會被重定向,第二個則不會,將直接出現最上麵的那一堆堆的異常信息。
解決辦法:
很簡單,就是上麵提到的 環形重定向的參數設置了,加上就好了。
這裏還要強調一點就是如果你不複寫 setEnableRedirects 方法的話,那麼最好千萬不要調用他,一旦調用他就會重置 handle 導致出現前麵說到的各種問題,
僅在需要禁止重定向的時候調用該方法設置為 false
血淚教訓啊,浪費了一天的青春,感歎下其實很多技術博客裏的文章,並不是你看到的簡簡單單的一個個字符,背後都是無數程序猿們的血淚和無悔青春,用生命的代價換來的。
最後更新:2017-04-03 12:55:24