最近在使用Apache HttpClient4.x時發現如果出現循環重定向的話就會出現bug問題了,這樣導致服務器無法正常訪問,會一直跳來跳去了,下面我來給大家介紹解決此問題的方法.
在Apache HttpClient 4.0里有個循環重定向的bug,當服務器試圖正常的從域名A跳轉到B的時候就會發生,我是在 Vevb.com 跳 www.49028c.com 的時候發現的,換過最新版也發現還是有這個問題.
跟蹤了DefaultRequestDirector.java之后發現,它在內部創建了一個HttpRedirect對象來處理重定向,這個對象會重用你之前的HttpGet對象里的HTTP 頭,導致這個bug的根源在于,連Host頭也用了,這表示重定向到的新域名如果和老域名如果是同一組集群,那么服務器會試圖重新發一個重定向請求,這樣就造成了HttpClient拋出CircularRedirectException.
我是派生了DefaultRequestDirector類來改掉這個問題,代碼如下:
- public class RedirectRequestDirector extends DefaultRequestDirector
- {
- RedirectRequestDirector(
- final HttpRequestExecutor requestExec,
- final ClientConnectionManager conman,
- final ConnectionReuseStrategy reustrat,
- final ConnectionKeepAliveStrategy kastrat,
- final HttpRoutePlanner rouplan,
- final HttpProcessor httpProcessor,
- final HttpRequestRetryHandler retryHandler,
- final RedirectHandler redirectHandler,
- final AuthenticationHandler targetAuthHandler,
- final AuthenticationHandler proxyAuthHandler,
- final UserTokenHandler userTokenHandler,
- final HttpParams params)
- {
- super(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, userTokenHandler, params);
- }
- @Override
- protected RoutedRequest handleResponse(RoutedRequest roureq,
- HttpResponse response,
- HttpContext context)
- throws HttpException, IOException
- {
- RoutedRequest req = super.handleResponse(roureq, response, context);
- if(req != null)
- {
- String redirectTarget = req.getRoute().getTargetHost().getHostName();
- req.getRequest().getOriginal().setHeader("Host", redirectTarget);//開源代碼Vevb.com
- }
- return req;
- }
- }
這里修改了Host頭為試圖重定向的主機名,還需要修改 DefaultHttpClient,代碼如下:
- public class RedirectHttpClient extends DefaultHttpClient
- {
- @Override
- protected RequestDirector createClientRequestDirector(
- final HttpRequestExecutor requestExec,
- final ClientConnectionManager conman,
- final ConnectionReuseStrategy reustrat,
- final ConnectionKeepAliveStrategy kastrat,
- final HttpRoutePlanner rouplan,
- final HttpProcessor httpProcessor,
- final HttpRequestRetryHandler retryHandler,
- final RedirectHandler redirectHandler,
- final AuthenticationHandler targetAuthHandler,
- final AuthenticationHandler proxyAuthHandler,
- final UserTokenHandler stateHandler,
- final HttpParams params) {
- return new RedirectRequestDirector(
- requestExec,
- conman,
- reustrat,
- kastrat,
- rouplan,
- httpProcessor,
- retryHandler,
- redirectHandler,
- targetAuthHandler,
- proxyAuthHandler,
- stateHandler,
- params);
- }
- }
現在就能正常處理跳轉了.
新聞熱點
疑難解答