使用HttpClient下載

一、HttpClient簡介

HttpClient是一個Apache軟體基金會下的開源Java HTTP客戶端庫,支持最新的HTTP/1.1協議規範。HttpClient以URL方式連向伺服器並獲取數據,因此HttpClient在處理HTTP與HTTPS協議方面表現出色。

使用HttpClient可以輕鬆地進行HTTP請求。相比於JSoup,HttpClient提供了更多的配置參數、更加豐富的Header設置和HTTP認證等功能,是一個更完善的方案。

在Android開發中,我們經常使用HttpClient下載圖片或者數據,因此HttpClient的使用非常重要。

二、HttpClient的網路請求流程

HttpClient的網路請求流程其實也很簡單,就是創建HttpClient對象、創建HttpGet/HttpPost對象,最後執行請求並處理響應。具體流程及代碼如下:

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
String result = EntityUtils.toString(httpEntity);

首先,我們需要使用HttpClients.createDefault()方法創建一個CloseableHttpClient對象。創建完成後,就可以使用HttpGet或者HttpPost對象進行請求的創建了。

這裡以HttpGet為例,使用HttpGet對象可以通過構造函數或者setURI()方法設置請求url。執行請求後,返回一個HttpResponse對象,可以通過獲取HttpEntity來獲取響應數據。最後使用EntityUtils.toString()方法將HttpEntity轉換成String,在進行後續處理。

三、設置請求參數

HttpClient可以非常靈活地定製請求參數,如設置請求頭、請求體、連接超時、讀取超時、代理等等,下面我們將一一介紹。

1. 設置請求頭

我們可以使用setHeader()方法進行自定義請求頭,或者使用setDefaultHeaders()方法設置默認請求頭,代碼如下:

HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
httpGet.setHeader("Referer", referer);

這裡我們設置了User-Agent和Referer兩個請求頭。User-Agent是指瀏覽器類型,在不同瀏覽器中會有不同的值。Referer是指請求發出時所在頁面的URL地址,是反映當前請求所在頁面的重要標識。

2. 設置請求體

HTTP的POST請求通常需要在請求體中傳遞數據,HttpClient可以通過setEntity()方法設置請求體。而常用的方法是使用UrlEncodedFormEntity來傳遞鍵值對參數,代碼如下:

HttpPost httpPost = new HttpPost(url);
List list = new ArrayList();
list.add(new BasicNameValuePair("username", "123456"));
list.add(new BasicNameValuePair("password", "abcdef"));
HttpEntity httpEntity = new UrlEncodedFormEntity(list);
httpPost.setEntity(httpEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
String result = EntityUtils.toString(httpResponse.getEntity());

這裡我們使用HttpPost對象,並創建一個List集合來存儲鍵值對參數,最後使用UrlEncodedFormEntity將鍵值對文本轉換為HTTP請求實體。

3. 設置連接超時和讀取超時

HttpClient可以進行連接超時和讀取超時設置,以確保正常的請求服務和避免請求超時。實現代碼如下:

RequestConfig.Builder builder = RequestConfig.custom();
builder.setConnectTimeout(10000);
builder.setSocketTimeout(30000);
RequestConfig requestConfig = builder.build();
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(requestConfig);
HttpResponse httpResponse = httpClient.execute(httpGet);

這裡我們通過RequestConfig.Builder進行設置超時時間,設置了10秒的連接超時和30秒的讀取超時,最後通過setConfig()方法設置到HttpGet對象中。

4. 設置代理

HttpClient也可以設置代理,以實現一些防爬蟲技巧。可以使用HttpHost類來代表代理的主機和埠。代碼如下:

HttpHost proxy = new HttpHost("127.0.0.1", 8888);
RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).build();
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(requestConfig);
HttpResponse httpResponse = httpClient.execute(httpGet);

這裡我們使用HttpHost對象來表示代理主機和埠,然後將其設置到RequestConfig中,並使用setConfig()方法將配置設置到HttpGet對象中。

四、常見問題處理

1. Https請求

HttpClient訪問Https請求需要導入SSL證書,否則會報如下異常:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

我們可以通過加入信任所有證書的方式解決該問題。代碼如下:

public static CloseableHttpClient createSSLClientDefault(){
    SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
        public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            return true;
        }
    }).build();
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
    return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}

其中TrustStrategy表示完全信任請求的網站,也可以自定義信任證書庫。

2. 下載文件

HttpClient也可以用來下載文件。我們可以使用HttpGet方法獲取InputStream,然後將其寫入文件。代碼如下:

HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
InputStream inputStream = httpResponse.getEntity().getContent();
FileOutputStream fos = new FileOutputStream("D:/test.jpg");
byte[] buffer = new byte[4096];
int length;
while ((length = inputStream.read(buffer)) != -1) {
    fos.write(buffer, 0, length);
}
fos.flush();
inputStream.close();
fos.close();

3. 大文件下載

對於大文件下載,我們可以使用HttpClient的Range請求處理,分段讀取數據,減少網路傳輸的壓力。代碼如下:

HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Range", "bytes=0-1024000");
HttpResponse httpResponse = httpClient.execute(httpGet);
InputStream inputStream = httpResponse.getEntity().getContent();
FileOutputStream fos = new FileOutputStream("D:/test.jpg");
byte[] buffer = new byte[4096];
int length;
while ((length = inputStream.read(buffer)) != -1) {
    fos.write(buffer, 0, length);
}
fos.flush();
inputStream.close();
fos.close();

這裡我們使用Range請求,限制文件大小為0-1024000位元組,就可以分段下載了。

總結

上述就是HttpClient下載的詳細介紹,從HttpClient的簡介、網路請求流程、設置請求參數、常見問題處理等多個方面做了闡述。掌握了HttpClient下載的使用方法,對於爬蟲、Android開發等領域都非常重要。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/303077.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-31 11:49
下一篇 2024-12-31 11:49

相關推薦

發表回復

登錄後才能評論