当年用httpclient时踩过的那些坑
一、前言
httpclient是java开发中最常用的工具之一,通常大家会使用其中比较基础的api去调用远程。长期开发爬虫,会接触httpclient不常用的api,同时会遇到各式各样的坑,本文将总结这些年遇到的坑及相应的解决方案。
二、问题及解决方案
问题1:Received fatal alert: handshake_failure
问题背景
开发某省份移动爬虫时,加载首页会报标题错误,尝试各种办法都不好使,后来发现换了jdk1.8就可以了。经过长达一个星期源码探寻,发现错误源头是http在握手时,加密算法不支持。
jdk1.8以下版本不支持256位(TLS_DHE_RSA_WITH_AES_256_CBC_SHA )
解决方案
1、下载jce扩展包 http://www.oracle.com/technetwork/cn/java/javase/downloads/jce-7-download-432124.html
2、替换/jre/lib/security/里面的两个jar
3、覆盖后如果报错The jurisdiction policy files are not signed by a trusted signer!,说明下载的版本不对,要下对应jdk版本的。
问题2:Certificates does not conformto algorithm constraints
问题背景
用mvn打包时报错, security.cert.CertificateException: Certificates does not conform toalgorithm constraints
原因是在java1.6之后的这个配置文件中,认为MD2的加密方式安全性太低,因而不支持这种加密方式,同时也不支持RSA长度小于1024的密文。
需要修改 JAVA_HOME/jre/lib/security/java.security #jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
但是这样做需要把每台机器都改一遍,如果新加机器忘记改了,就会继续报错。因此需要一套方法,只在代码层解决问题。
解决方案
经查源码发现了触发问题的代码位置,通过强制继承SSLContextBuilder,并强制把private的keymanagers和trustmanagers的值置空就可以解决这个问题了。
代码如下:
static class MySSLContextBuilder extends SSLContextBuilder {
static final String TLS = "TLS";
static final String SSL = "SSL";
private String protocol;
private Set keymanagers;
private Set trustmanagers;
private SecureRandom secureRandom;
public MySSLContextBuilder() {
super();
this.keymanagers = new HashSet();
this.trustmanagers = new HashSet();
}
}
问题3:超时时间不生效
问题背景
很多人在使用httpclient时会到网上去找例子,例子中经常会有类似这样的设置
httpGet.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, !isAutoRelocal);
使用上述方法发送httpclient,在读取配置时,如果发现getParams不为空,则会使得以前设置的所有参数都失效,而使用这里设置的,结果是导致超时时间失效。
解决方案
request.getParams().setParameter是过期方法,其中每一项参数在RequestConfig里都有对应的,遍历出来替换一遍即可。
boolean isRedirect = true;
if(request != null) {
HttpParams params = request.getParams();
if (params instanceof HttpParamsNames) {
// 暂时只支持这个类型
isRedirect = params.getBooleanParameter(
ClientPNames.HANDLE_REDIRECTS, true);
}
// 清空request
request.setParams(new BasicHttpParams());
}
) {
builder = RequestConfig.custom().setConnectionRequestTimeout(timeOut).setConnectTimeout(timeOut).setSocketTimeout(timeOut).setRedirectsEnabled(isRedirect).setCookieSpec(CookieSpecs.BEST_MATCH);
} else {
builder = RequestConfig.custom().setConnectionRequestTimeout(connectionTimeout).setConnectTimeout(connectionTimeout).setRedirectsEnabled(isRedirect).setSocketTimeout(socketTimeout).setCookieSpec(CookieSpecs.BEST_MATCH);
}
问题4:fildder监听问题
问题背景
开发爬虫经常会使用fildder来监控网络请求,但是使用httpclient时想用fildder会很难,网上查各种办法都不好用。
下面为大家来排个错,使用下面方法就可以完美解决这个问题,让fildder监控更容易。
解决方案
首先java端
// client builder
HttpClientBuilder builder = HttpClients.custom();
if(useFidder) {
// 默认fidder写死
builder.setProxy());
}
fildder端
tools->fiddler options->https->actions->export root certificate to ... \bin\keytool.exe -import -file C:\Users\\Desktop\FiddlerRoot.cer -keystore FiddlerKeystore -alias Fiddler
问题5:支持gzip
问题及解决方案
有些网站返回进行了gzip压缩,返回内容是压缩的结果,需要解压。
代码如下:
HttpClient wrappedHttpClient = builder.setUserAgent(requestUA)
.addInterceptorLast(new HttpResponseInterceptor() {
@Override
public void process(HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
HttpEntity httpEntity = httpResponse.getEntity();
Header header = httpEntity.getContentEncoding();
if (header != null) {
for (HeaderElement element : header.getElements()) {
if ("gzip".equalsIgnoreCase(element.getName())) {
httpResponse.setEntity(new GzipDecompressingEntity(httpResponse.getEntity()));
}
}
}
}
})
作者:刘鹏飞
来源:宜信技术学院
当年用httpclient时踩过的那些坑的更多相关文章
- UWP中重用C/C++代码时踩过的一些坑
标题中提到的UWP,主要是指用C#来写UWP的主工程,开发过程中可能需要调用C/C++实现的库. 为什么需要调用C/C++的库呢,举个例子,开源库OpenSSL实现了许多加密算法,稳定快速,我们想在应 ...
- 在配置tensorflow时踩的无数个坑
在下午尝试配置tensorflow环境时,遇到了许多天坑,讲真的心态炸了好几次,特此写下这篇记录,希望能给看到朋友一点帮助. 先说一下这抓狂的一天的起因,比赛项目想用SVM进行一下数据分析,除了常规的 ...
- 记录初学者学习Hive时踩过的坑
1. 缺少MySQL驱动包 1.1 问题描述 Caused by: org.datanucleus.store.rdbms.connectionpool.DatastoreDriverNotFound ...
- 使用Ajax中get请求发送Token时踩的那些坑
在使用惯了各种牛X的插件以后,在使用原生组件写一些小东西的时候总是有踩不完的坑! 今天就来说一说我使用原生ajax请求时踩得坑: 下面是我的代码: var xmlhttp; if (window.XM ...
- Spring Data JPA使用findAllOrderBy时踩的坑
Spring Data JPA使用findAllOrderBy时踩的坑 按照以往的编程经验,我的写法是这样的: List<ActivityEntity> findAllOrderByWis ...
- 三分之一的程序猿之社交类app踩过的那些坑
三分之一的程序猿之社交类app踩过的那些坑 万众创新,全民创业.哪怕去年陌生人社交不管融资与否都倒闭了不知道多少家,但是依然有很多陌生人社交应用层出不穷的冒出来.各种脑洞大开,让人拍案叫起. 下面我们 ...
- 【Fine原创】JMeter分布式测试中踩过的那些坑
最近因为项目需要,研究了性能测试的相关内容,并且最终选用了jmeter这一轻量级开源工具.因为一直使用jmeter的GUI模式进行脚本设计,到测试执行阶段工具本身对资源的过量消耗给性能测试带来了瓶颈, ...
- 与webview打交道中踩过的那些坑
随着HTML5被越来越多的用到web APP的开发当中,webview这一个神器便日渐凸显出重要地位.简要的说,webview能够在移动应用中开辟出一个窗口,在里面显示html页面,css以及js代码 ...
- 安装python爬虫scrapy踩过的那些坑和编程外的思考
这些天应朋友的要求抓取某个论坛帖子的信息,网上搜索了一下开源的爬虫资料,看了许多对于开源爬虫的比较发现开源爬虫scrapy比较好用.但是以前一直用的java和php,对python不熟悉,于是花一天时 ...
随机推荐
- android 之 GridView
GridView 的用法基本与ListView类似. 程序布局文件main.xml <?xml version="1.0" encoding="utf-8" ...
- 向php数组添加元素的方法哪种更高效
$arr = array(); // 第一种 array_push($arr, 'test'); // 第二种 $arr[] = 'test'; 参考PHP官方文档:http://php.net/ma ...
- POJ 2106-Boolean Expressions,双栈运用类似表达式求值!
Boolean Expressions 首先声明此题后台可能极水(毕竟这种数据不好造!).昨天写了一天却总是找不到bug,讨论区各种数据都过了,甚至怀疑输入有问题,但看到gets也可以过,难道是思路错 ...
- 九度oj 1480
题目描述: 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, ...,aN),我们可以得到一些上升的子序列( ...
- BZOJ 4811 [Ynoi2017]由乃的OJ ——Link-Cut Tree
直接维护按照顺序经过每一段,初始的1可以变成什么,初始为0可以变成什么. 然后答案就可以和起床困难综合征一样贪心处理了. 写起来并不好写. 发现交换左右子树之后答案会改变,GG 调了一天,最后还是T掉 ...
- POJ 2155 Matrix【二维线段树】
题目大意:给你一个全是0的N*N矩阵,每次有两种操作:1将矩阵中一个子矩阵置反,2.查询某个点是0还是1 思路:裸的二维线段树 #include<iostream>#include< ...
- 刷题总结——魔法森林(bzoj3669)
题目: Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同 ...
- Java 线程池的原理与实现学习(二)
java类库中提供的线程池简介: java提供的线程池更加强大,相信理解线程池的工作原理,看类库中的线程池就不会感到陌生了. execute(Runnable command):履行Ruannable ...
- 玩转css样式选择器----利用padding实现元素等比缩放
- cout与cerr
cout对应于标准输出流,默认情况下是显示器.这是一个被缓冲的输出,可以被重定向. cerr对应标准错误流,用于显示错误消息.默认情况下被关联到标准输出流,但它不被缓冲,也就说错误消息可以直接发送到显 ...