閱讀971 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  上一篇:go linux驅動開發--中斷:tasklet實現中斷底半部
  下一篇:go Linux Eclipse代碼提示功能設置(Java & C/C++)