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
血泪教训啊,浪费了一天的青春,感叹下其实很多技术博客里的文章,并不是你看到的简简单单的一个个字符,背后都是无数程序猿们的血泪和无悔青春,用生命的代价换来的。
AsyncHttpClient 中的重定向和 setEnableRedirects 方法异常解决的更多相关文章
- github for window 中 git shell 设置代理方法和解决ssl证书错误的问题
体验了一下传说中的 github for windows(操作git有很多的方法,我还没有学会,所以找了个简单的方法),听说用起来还不错,毕竟也开始接触了github.下载地址是 http://win ...
- LoadRunner中InvokeMethod failure: 外部组件发生异常解决办法
-82801 abnormal termination,caused by mdrv process termination -29996 error:process mmdrv.exe was no ...
- linux中nginx重定向方法总结
linux中nginx 301重定向跳转方法总结 第一种情况:访问aaaaaaa站定向到bbbbbbbbbbb站 复制代码代码如下: server { server_naaaaaaame www.aa ...
- 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...
- 痞子衡嵌入式:MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法. 前段时间痞子衡写了一篇 <在IAR开发环境下将关键函数重 ...
- 痞子衡嵌入式:在MDK开发环境下将关键函数重定向到RAM中执行的几种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在MDK开发环境下将关键函数重定向到RAM中执行的几种方法. 这个关键函数重定向到 RAM 中执行系列文章,痞子衡已经写过 <IA ...
- PHP 中的 9 个魔术方法
这个标题有点牵强因为php有不只9种魔术方法, 但是这些将会引导你使用php魔术方法一个好的开始.它可能魔幻,但是并不需要魔杖. 这些'魔术'方法拥有者特殊的名字,以两个下划线开始,表示这些方法在ph ...
- Tornado 中的 get() 或 post() 方法
---恢复内容开始--- Tornado 中的 get() 或 post() 方法 请求处理程序和请求参数 Tornado 的 Web 程序会将 URL 或者 URL 范式映射到 tornado.we ...
- Hibernate中evict方法和clear方法说明
Hibernate中evict方法和clear方法说明 先创建一个对象,然后调用session.save方法,然后调用evict方法把该对象清除出缓存,最后提交事务.结果报错: Exception i ...
随机推荐
- c/c++操作访问数据,是堆中的数据快还是栈中的数据快
这里的问题其实问的是对堆与栈的数据访问有什么不同. 观察如下代码: #include<stdio.h> #include<iostream> using namespace s ...
- DirectX And Com
Windows游戏编程读书笔记(5)——初识DirectX和COM 一.COM 1.什么是COM对象 一个COM对象事实上是一个或一套实现了大量接口的C++类 2.COM的优点 不用重新编译你的程序就 ...
- 长度为n的数组,有一个数重复出现了n/2+1次,找出(三种方法)
问题: 长度为n的数组,有一个数重复出现了n/2+1次,找出这个数: 解决: 比较直接的思路是遍历每个元素,让其与剩下其他元素比较,相等一次计数器sum++,直到sum=n/2+1为止: #inc ...
- JS放大镜特效(兼容版)
原理 1.鼠标在小图片上移动时,通过捕获鼠标在小图片上的位置,定位大图片的相应位置 设计 1.页面元素:小图片.大图片.放大镜 2.技术点:事件捕获.定位 1)onmouseover:会在鼠标指针移动 ...
- linux history 命令详解
linux history 命令详解 显示命令执行时间 linux shell 具有history 功能,即会记录已经执行过的命令,但是默认是不显示命令的执行时间,命令的执行时间,history 已经 ...
- linux下php-5.4.8.tar.gz编译安装全攻略
首先安装基础依赖组建,注:这些依赖组建也是LINUX+PHP+MYSQL+APACHE+NGINX+MEMCACHED时必要的系统组件 LANG=C yum -y install gcc gcc-c ...
- while循环的基本用法
while是常用的循环结构之一 1.格式: while(条件){ } 2.基本知识点 1)puts(“字符串”).换行输出一个字符串 2)死循环.. while(1){ } 代码如下:
- apache cxf笔记之Spring客户端访问和调用webservice服务
继续上次的spring服务的问题,这边介绍一种spring配置客户端的方法. 1.src目录下新建client-beans.xml文件 <?xml version="1.0" ...
- Android 关于ListView中按钮监听的优化问题(方法一)
在Android应用开发过程中经常会用到ListView,并且每次在item中都要对点击事件进行监听.在给按钮添加OnClickListener时,一般会下意识的在getView()中找到每一个But ...
- Linux进程分配内存的两种方式--brk() 和mmap()
如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor faul ...