一、前言

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时踩过的那些坑的更多相关文章

  1. UWP中重用C/C++代码时踩过的一些坑

    标题中提到的UWP,主要是指用C#来写UWP的主工程,开发过程中可能需要调用C/C++实现的库. 为什么需要调用C/C++的库呢,举个例子,开源库OpenSSL实现了许多加密算法,稳定快速,我们想在应 ...

  2. 在配置tensorflow时踩的无数个坑

    在下午尝试配置tensorflow环境时,遇到了许多天坑,讲真的心态炸了好几次,特此写下这篇记录,希望能给看到朋友一点帮助. 先说一下这抓狂的一天的起因,比赛项目想用SVM进行一下数据分析,除了常规的 ...

  3. 记录初学者学习Hive时踩过的坑

    1. 缺少MySQL驱动包 1.1 问题描述 Caused by: org.datanucleus.store.rdbms.connectionpool.DatastoreDriverNotFound ...

  4. 使用Ajax中get请求发送Token时踩的那些坑

    在使用惯了各种牛X的插件以后,在使用原生组件写一些小东西的时候总是有踩不完的坑! 今天就来说一说我使用原生ajax请求时踩得坑: 下面是我的代码: var xmlhttp; if (window.XM ...

  5. Spring Data JPA使用findAllOrderBy时踩的坑

    Spring Data JPA使用findAllOrderBy时踩的坑 按照以往的编程经验,我的写法是这样的: List<ActivityEntity> findAllOrderByWis ...

  6. 三分之一的程序猿之社交类app踩过的那些坑

    三分之一的程序猿之社交类app踩过的那些坑 万众创新,全民创业.哪怕去年陌生人社交不管融资与否都倒闭了不知道多少家,但是依然有很多陌生人社交应用层出不穷的冒出来.各种脑洞大开,让人拍案叫起. 下面我们 ...

  7. 【Fine原创】JMeter分布式测试中踩过的那些坑

    最近因为项目需要,研究了性能测试的相关内容,并且最终选用了jmeter这一轻量级开源工具.因为一直使用jmeter的GUI模式进行脚本设计,到测试执行阶段工具本身对资源的过量消耗给性能测试带来了瓶颈, ...

  8. 与webview打交道中踩过的那些坑

    随着HTML5被越来越多的用到web APP的开发当中,webview这一个神器便日渐凸显出重要地位.简要的说,webview能够在移动应用中开辟出一个窗口,在里面显示html页面,css以及js代码 ...

  9. 安装python爬虫scrapy踩过的那些坑和编程外的思考

    这些天应朋友的要求抓取某个论坛帖子的信息,网上搜索了一下开源的爬虫资料,看了许多对于开源爬虫的比较发现开源爬虫scrapy比较好用.但是以前一直用的java和php,对python不熟悉,于是花一天时 ...

随机推荐

  1. Java设计模式学习三-----工厂模式

    工厂模式 工厂模式(Factory Pattern)是Java中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,创建对象时不会对客户端暴露创建逻 ...

  2. selenium常见控件操作

    下拉选择框 第一种方法:from selenium.webdriver.support.select import Select# 实例化一个Select类的对象 selector = Select( ...

  3. (总结)CentOS Linux使用crontab运行定时任务详解

    安装crontab:yum install crontabs 说明:/sbin/service crond start //启动服务/sbin/service crond stop //关闭服务/sb ...

  4. 2011 Michigan Invitational Programming Contest

    Crossings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463 Description ...

  5. [POJ1741]Tree(点分治模板)

    传送门 良心解析 其实以前在求某段序列上的区间统计问题时就碰到过类似于这样的思想. 当时的区间统计问题思路大致是这样: 选取一个点作为中间点,从这个点的左边和右边统计出满足条件的点对.然后当前的中间点 ...

  6. 请问 内网的 dns服务器 为什么和 外网的dns服务器 一样??

    公司内的内网使用192.169.X.X的内网地址,但是在DNS段填写的是210.34.X.X,显然这是一个公网固定IP,我不明白的是:为什么内部网客户端使用的DNS服务器是公网上的IP呢?内网客户端能 ...

  7. Codeforces956D. Contact ATC

    $n \leq 100000$个飞机在坐标轴上,给坐标给速度,坐标速度异号,还有一个风速在$[-w,w]$区间,$w$比最小的速度绝对值要小.由于风速不知道,所以问有多少对飞机可能在原点相遇. 思维定 ...

  8. R语言入门-画图(二)--heatmap

    一.函数参数: pheatmap参数: treeheight_row #横有多长 treeheight_col #竖有多长 cluster_cols=FLASE #单一方向聚类,也就是只有一边有树状结 ...

  9. laravel 查询构造器2

    //查询构造器 public function query() { //获取所有的数据 $student = DB::table('student')->get(); var_dump($stu ...

  10. @InsertProvider 根据bean属性,自动生成插入sql语句

    以Test为例,用mybatis的@InsertProvider的注解插入数据的时候,每次都要写类似于 Mapper类 @Mapper public interface TestDao { @Inse ...