今天使用 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

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

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

  1. github for window 中 git shell 设置代理方法和解决ssl证书错误的问题

    体验了一下传说中的 github for windows(操作git有很多的方法,我还没有学会,所以找了个简单的方法),听说用起来还不错,毕竟也开始接触了github.下载地址是 http://win ...

  2. LoadRunner中InvokeMethod failure: 外部组件发生异常解决办法

    -82801 abnormal termination,caused by mdrv process termination -29996 error:process mmdrv.exe was no ...

  3. linux中nginx重定向方法总结

    linux中nginx 301重定向跳转方法总结 第一种情况:访问aaaaaaa站定向到bbbbbbbbbbb站 复制代码代码如下: server { server_naaaaaaame www.aa ...

  4. 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...

  5. 痞子衡嵌入式:MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法. 前段时间痞子衡写了一篇 <在IAR开发环境下将关键函数重 ...

  6. 痞子衡嵌入式:在MDK开发环境下将关键函数重定向到RAM中执行的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在MDK开发环境下将关键函数重定向到RAM中执行的几种方法. 这个关键函数重定向到 RAM 中执行系列文章,痞子衡已经写过 <IA ...

  7. PHP 中的 9 个魔术方法

    这个标题有点牵强因为php有不只9种魔术方法, 但是这些将会引导你使用php魔术方法一个好的开始.它可能魔幻,但是并不需要魔杖. 这些'魔术'方法拥有者特殊的名字,以两个下划线开始,表示这些方法在ph ...

  8. Tornado 中的 get() 或 post() 方法

    ---恢复内容开始--- Tornado 中的 get() 或 post() 方法 请求处理程序和请求参数 Tornado 的 Web 程序会将 URL 或者 URL 范式映射到 tornado.we ...

  9. Hibernate中evict方法和clear方法说明

    Hibernate中evict方法和clear方法说明 先创建一个对象,然后调用session.save方法,然后调用evict方法把该对象清除出缓存,最后提交事务.结果报错: Exception i ...

随机推荐

  1. vj1010:高精乘+细心模拟

    这题的话思路挺简单的,主要是打一个高精乘,然后考虑一些细节的东西 码得挺少时间的,但是调错调了很久... 讲一下思路吧: 就是读入的时候,先把小数点去掉,mark一下小数点的位置 去掉小数点之后也就进 ...

  2. 类图class的关联关系(聚合、组合)

    类图class的关联关系(聚合.组合) 关联的概念 关联用来表示两个或多个类的对象之间的结构关系,它在代码中表现为一个类以属性的形式包含对另一个类的一个或多个对象的应用. 程序演示:关联关系(code ...

  3. 如何避免误用分布式事务(System.Transactions.TransactionScope)

    以下内容来源与:http://www.cyqdata.com/cyq1162/article-detail-54453 1:本地事务DbTransaction和分布式事务TransactionScop ...

  4. 业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份

    业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份 WinForm酒店管理软件--框架这篇随笔可以说是我写的最被大家争议的随笔,一度是支持和反对是一样的多.大家对我做的这个行业 ...

  5. Make Things Move -- Javascript html5版(二)实现最基本的Sprite类和stage管理对象

    现在这几篇写的都是比较基础的东西,有过相应开发经验的朋友可直接忽略啦. 计算机模拟的动画都是由很多静态的一连串影像(sprite)在一定帧率(fps)内逐帧播放出来的. 对于js来说,我们可以用提供的 ...

  6. jQuery表格排序组件-tablesorter

    一.引入文件 <script type="text/javascript" src="js/jquery.js"></script> & ...

  7. linux下面配置安装nodejs+npm

    linux下 多亏这一篇文章= =我就卡死在文章所说的这个点里 附大牛链接:http://blog.sitearth.com/nodejs%E4%B8%8A%E4%BD%BF%E7%94%A8mong ...

  8. 关于前端JS模块加载器实现的一些细节

    最近工作需要,实现一个特定环境的模块加载方案,实现过程中有一些技术细节不解,便参考 了一些项目的api设计约定与实现,记录下来备忘. 本文不探讨为什么实现模块化,以及模块化相关的规范,直接考虑一些技术 ...

  9. 为Exchange 2007 SCC 启用 SCR 副本-供需要的人使用!

    SCC 已经部署完整,接下来我们必须防范本地站点如果出现了完全的损坏怎么办? Exchange 2007 SP1 提供了另外一种高可用的方式,就是基于我们的SCR 模型,SCR 模型是基于SCC 本地 ...

  10. JSTL(JSP Standard Tag Library ,JSP标准标签库)

    JSTL标签之核心标签   JSTL(JSP Standard Tag Library ,JSP标准标签库)是一个实现 Web应用程序中常见的通用功能的定制标记库集,这些功能包括迭代和条件判断.数据管 ...