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

血泪教训啊,浪费了一天的青春,感叹下其实很多技术博客里的文章,并不是你看到的简简单单的一个个字符,背后都是无数程序猿们的血泪和无悔青春,用生命的代价换来的。

时间: 2025-01-29 12:44:47

AsyncHttpClient 中的重定向和 setEnableRedirects 方法异常解决的相关文章

nginx中301重定向二种方法

last – 基本上都用这个Flag.break – 中止Rewirte,不在继续匹配,redirect – 返回临时重定向的HTTP状态302,permanent – 返回永久重定向的HTTP状态301 有需要的朋友可参考参考.  代码如下 复制代码 server { server_name www.yfds.com.cn fdscom.cn; if ($host != 'yi1.com.cn' ) { rewrite ^/(.*)$ http://cc.com/$1 permanent; }

asp.net 中WinForm出现无法处理的异常解决办法

,然后进行处理,但是这段代码中用到了BeginInvoke的语句块,而我使用了匿名方法,那么在匿名方法中的异常,外面是捕捉不到的.所以会出现无法处理的异常情况,正确的代码应该这样:  代码如下 复制代码 this.BeginInvoke(new MethodInvoker(delegate() {     bool flag = false;     try     {         flag = service.Authentication();//此处可能造成异常         if (

java中spring security的remember me异常解决办法

 想想也不可能,网络中不会时不时出现cookie theft攻击吧.看了官方文档,也没给出解释,后来在oschina看到一篇分析的文章,才明白其中的缘由,文章<是谁动了我的cookie?Spring Security自动登录功能开发经历总结>. 从这篇文章的分析结合spring secutiy的源码来看,在每次持久化登录校验token完毕之后,会更新token的值并写入cookie.而token的校验是通过加密处理写入cookie中的字符串与持久化存储的token做对比看是否一致来判断登录信息

IIS中利用重定向URL来防止Access数据库被下载的方法

对于ASP+Access开发的网站,安全性最最让人担忧的就是Access数据库可以随意下载,当然我们可以通过一些修改数据库名称的手段进行尽量的防护,但归根结底是不彻底的.所以今天就来谈谈在IIS中利用重定向URL来防止Access数据库被下载的方法. 此方法需要你有IIS的管理权限,如果你使用的是虚拟主机,那估计没有办法了,呵呵.这里假设你有IIS的管理权限. 1.首先打开Internet 信息服务(IIS)管理器,在Internet 信息服务(IIS)管理器左边窗口中找到你数据库所在的文件夹,

JQuery中使用Ajax赋值给全局变量异常的解决方法

 本篇文章主要是对JQuery中使用Ajax赋值给全局变量异常的解决方法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 我们在用JQuery的Ajax从后台提取数据后想把它赋值给全局变量,但是却怎么都赋不进,为什么呢?   原因其实很简单,我们用的Ajax是异步操作,也就是说在你赋值的时候数据还没提取出来,你当然赋不进去,所以只要改成同步操作就行~   方法1:先设置同步在进行Ajax操作      代码如下: //在全局或某个需要的函数内设置Ajax异步为false,也就是同步

使用nodejs中httpProxy代理时候出现404异常的解决方法_node.js

在公司中使用nodejs构建代理服务器实现前后台分离,代码不能拿出来,然后出现httpProxy代理资源的时候老是出现404.明明被代理的接口是存在的.代码大概如下: var http = require('http'), httpProxy = require('http-proxy'); var proxy = httpProxy.createProxyServer({}); var server = http.createServer(function(req, res) { proxy.

php开发中的页面跳转方法总结

php页面跳转实现的功能就是将网站中一个网页跳转到另一个网页中.对于刚刚学习php语言的朋友来说,是必须要掌握的基础方法. 开发中的页面跳转方法总结-微信网页开发页面跳转"> 页面跳转可能是由于用户单击链接.按钮等触发的,也可能是系统自动产生的.页面自动跳转在web开发中经常用到,而且根据需求可以采用不同的跳转方式,比如提示操作信息后延时跳转等, 本文总结了web开发中常见的几种页面跳转方法. php header函数跳转 php的header函数非常强大,其中在页面url跳转方面也调用简

sql2008启动报错:应用程序的组件中发生了无法处理的异常和值不能为空viewinfo

sql2008 启动报错:应用程序的组件中发生了无法处理的异常和值不能为空 viewinfo(已解决!) 1.重启sql(无效) 2.,重启系统(无效) 3.重装.net(无效) 后发现问题出在 这是因为临时处理路径出现异常造成的,主要是C:\Users\Administrator\AppData\Local\Temp下的文件夹名为[2]的文件夹出现了问题,解决方法如下: 进入C:\Users\Administrator\AppData\Local\Temp路径,也可以在C盘地址栏输入此路径进入

JavaScript中的this关键字使用方法总结

 这篇文章主要介绍了JavaScript中的this关键字使用方法总结,本文讲解了作为对象方法调用.作为函数调用.作为构造函数调用.使用 apply 或 call 调用等内容,需要的朋友可以参考下     在javascritp中,不一定只有对象方法的上下文中才有this, 全局函数调用和其他的几种不同的上下文中也有this指代. 它可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式.JavaScript 中函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用