當年用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時會到網上去找例子,例子中經常會有類似這樣的設定
使用上述方法傳送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()); } if(timeOut > 0) { 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(new HttpHost("127.0.0.1", 8888)); }
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())); } } } } })
作者:劉鵬飛
來源: 宜信技術學院
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69918724/viewspace-2654441/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- uniapp之那些年踩過的坑APP
- IT人,那些年,一起踩過的坑
- 講課這些天(二):那些年踩過的坑
- 那些年我們一起踩過的Dubbo坑
- 那些年你踩過的坑,都在這裡了~| 掘金技術徵文
- Vue2.0配置mint-ui踩過的那些坑VueUI
- Go 開發踩過的那些坑(適合Java轉Go)GoJava
- 關於最近開發小程式中踩過的那些坑
- 那些最全面的Windows10安裝pytorch踩過的坑以及如何應用WindowsPyTorch
- GeoServer 踩過的坑Server
- 我在秋招中踩過的那些坑|掘金技術徵文
- 那些年走過下劃線的坑
- 那些年踩過的坑——input輸入框 ios端 readyonly 點選出現游標iOS
- 那些年踩過的坑——h5頁面在ios端點選高亮閃爍H5iOS
- JasperReport 中踩過的坑
- 改bug時踩的坑
- 那些年走過ArrayList迴圈remove的坑REM
- 你踩過flutter的坑嗎Flutter
- 解析資料踩過的坑
- 親自踩過的vue的坑Vue
- Compose 延遲列表踩過的坑
- 安裝 Laravel/horizon 踩過的坑Laravel
- wepy小程式踩過的坑(1)
- 【踩坑指南】執行緒池使用不當的五個坑執行緒
- 時區的坑,別再踩了!
- 踩過的坑(一)——web容器升級Web
- linux環境壓測踩過的坑Linux
- Redis 叢集部署及踩過的坑Redis
- vue專案中踩過的element的坑Vue
- 手寫那些年用過的React路由React路由
- 那些年,小島秀夫讓我們上過的當
- #兩年移動端踩坑,遇到的那些不得不說的bug及修復
- 異常處理遇到過的那些坑
- IDEA建立Maven專案中踩過的坑IdeaMaven
- 記錄自己在tensorflow中踩過的坑
- 小程式的這些坑你踩過嗎?
- 使用ABP框架中踩過的坑系列2框架
- 微信JS-SDK踩過的那些小坑坑JS