最近在使用Apache HttpClient4.x时发现如果出现循环重定向的话就会出现bug问题了,这样导致服务器无法正常访问,会一直跳来跳去了,下面我来给大家介绍解决此问题的方法.
在Apache HttpClient 4.0里有个循环重定向的bug,当服务器试图正常的从域名A跳转到B的时候就会发生,我是在 Vevb.com 跳 www.Vevb.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);
- }
- }
现在就能正常处理跳转了.
新闻热点
疑难解答