那些年用httpclient時踩過的一些坑
一、前言
httpclient是java開發(fā)中最常用的工具之一,通常大家會使用其中比較基礎(chǔ)的api去調(diào)用遠程。長期開發(fā)爬蟲,會接觸httpclient不常用的api,同時會遇到各式各樣的坑,本文將總結(jié)這些年遇到的坑及相應的解決方案。
二、問題及解決方案
問題1:Received fatal alert: handshake_failure
問題背景
開發(fā)某省份移動爬蟲時,加載首頁會報標題錯誤,嘗試各種辦法都不好使,后來發(fā)現(xiàn)換了jdk1.8就可以了。經(jīng)過長達一個星期源碼探尋,發(fā)現(xiàn)錯誤源頭是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
但是這樣做需要把每臺機器都改一遍,如果新加機器忘記改了,就會繼續(xù)報錯。因此需要一套方法,只在代碼層解決問題。
解決方案
經(jīng)查源碼發(fā)現(xiàn)了觸發(fā)問題的代碼位置,通過強制繼承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時會到網(wǎng)上去找例子,例子中經(jīng)常會有類似這樣的設(shè)置
httpGet.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, !isAutoRelocal);
使用上述方法發(fā)送httpclient,在讀取配置時,如果發(fā)現(xiàn)getParams不為空,則會使得以前設(shè)置的所有參數(shù)都失效,而使用這里設(shè)置的,結(jié)果是導致超時時間失效。
解決方案
request.getParams().setParameter是過期方法,其中每一項參數(shù)在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監(jiān)聽問題
問題背景
開發(fā)爬蟲經(jīng)常會使用fildder來監(jiān)控網(wǎng)絡請求,但是使用httpclient時想用fildder會很難,網(wǎng)上查各種辦法都不好用。
下面為大家來排個錯,使用下面方法就可以完美解決這個問題,讓fildder監(jiān)控更容易。
解決方案
首先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
問題及解決方案
有些網(wǎng)站返回進行了gzip壓縮,返回內(nèi)容是壓縮的結(jié)果,需要解壓。
代碼如下:
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()));
}
}
}
}
})
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
- java使用httpclient模擬post請求和get請求示例
- java使用httpclient發(fā)送post請求示例
- 使用httpclient無需證書調(diào)用https的示例(java調(diào)用https)
- JAVA利用HttpClient進行POST請求(HTTPS)實例
- java發(fā)送HttpClient請求及接收請求結(jié)果過程的簡單實例
- java實現(xiàn)HttpClient異步請求資源的方法
- 使用java的HttpClient實現(xiàn)多線程并發(fā)
- HttpClient 在Java項目中的使用詳解
- Java利用HttpClient模擬POST表單操作應用及注意事項
- java web中 HttpClient模擬瀏覽器登錄后發(fā)起請求
相關(guān)文章
SpringFramework中的數(shù)據(jù)校驗方式
這篇文章主要介紹了SpringFramework中的數(shù)據(jù)校驗方式,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-12-12

