Apache HttpClient
1、簡易架構圖
2、Apache HttpClient 簡介
HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,並且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient。
HttpClient 相比傳統 JDK 自帶的 URLConnection
,增加了易用性和靈活性,它不僅是客戶端發送 HTTP 請求變得容易,而且也方便了開發人員測試接口(基於 HTTP 協議的),即提高了開發的效率,也方便提高代碼的健壯性。因此熟練掌握 HttpClient 是很重要的必修內容,掌握 HttpClient 后,相信對於 HTTP 協議的了解會更加深入。
3、Apache HttpClient 特性
- 基於標准、純凈的 Java 語言。實現了 HTTP 1.0 和 HTTP 1.1
- 以可擴展的面向對象的結構實現了 HTTP 全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。
- 支持 HTTPS 協議。
- 通過 HTTP 代理建立透明的連接。
- 利用 CONNECT 方法通過 HTTP 代理建立隧道的 HTTPS 連接。
- Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos 認證方案。
- 插件式的自定義認證方案。
- 便攜可靠的套接字工廠使它更容易的使用第三方解決方案。
- 連接管理器支持多線程應用。支持設置最大連接數,同時支持設置每個主機的最大連接數,發現並關閉過期的連接。
- 自動處理 Set-Cookie 中的 Cookie。
- 插件式的自定義 Cookie 策略。
- Request 的輸出流可以避免流中內容直接緩沖到 Socket 服務器。
- Response 的輸入流可以有效的從 Socket 服務器直接讀取相應內容。
- 在 HTTP 1.0 和 HTTP 1.1 中利用 KeepAlive 保持持久連接。
- 直接獲取服務器發送的 response code 和 headers。
- 設置連接超時的能力。
- 實驗性的支持 HTTP 1.1 response caching。
- 源代碼基於 Apache License 可免費獲取。
4、Apache HttpClient 使用流程
使用 HttpClient 發送請求、接收響應很簡單,一般需要如下幾步即可。
- 創建
HttpClient
對象。 - 創建請求方法的實例,並指定請求 URL。如果需要發送 GET 請求,創建
HttpGet
對象;如果需要發送 POST 請求,創建HttpPost
對象。 - 如果需要發送請求參數,可調用
HttpGet
、HttpPost
共同的setParams(HttpParams params)
方法來添加請求參數;對於HttpPost
對象而言,也可調用setEntity(HttpEntity entity)
方法來設置請求參數。 - 調用
HttpClient
對象的execute(HttpUriRequest request)
發送請求,該方法返回一個HttpResponse
。 - 調用
HttpResponse
的getAllHeaders()
、getHeaders(String name)
等方法可獲取服務器的響應頭;調用HttpResponse
的getEntity()
方法可獲取HttpEntity
對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。 - 釋放連接。無論執行方法是否成功,都必須釋放連接
5、Apache HttpClient 使用實例
POM
pom.xml
配置如下:
<!-- Apache Http Begin -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.5</version>
</dependency>
<!-- Apache Http End -->
主要增加了 org.apache.httpcomponents:httpclient
、org.apache.httpcomponents:fluent-hc
、org.apache.httpcomponents:httpmime
三個依賴
創建 HttpGet 請求
案例代碼如下:
package com.cmcc.hello.httpclient;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class MyTest {
public static void main(String[] args) {
get();
}
private static void get() {
// 創建 HttpClient 客戶端
CloseableHttpClient httpClient = HttpClients.createDefault();
// 創建 HttpGet 請求
HttpGet httpGet = new HttpGet("http://localhost:8080/content/page?draw=1&start=0&length=10");
// 設置長連接
httpGet.setHeader("Connection", "keep-alive");
// 設置代理(模擬瀏覽器版本)
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
// 設置 Cookie
httpGet.setHeader("Cookie", "UM_distinctid=16442706a09352-0376059833914f-3c604504-1fa400-16442706a0b345; CNZZDATA1262458286=1603637673-1530123020-%7C1530123020; JSESSIONID=805587506F1594AE02DC45845A7216A4");
CloseableHttpResponse httpResponse = null;
try {
// 請求並獲得響應結果
httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
// 輸出請求結果
System.out.println(EntityUtils.toString(httpEntity));
} catch (IOException e) {
e.printStackTrace();
}
// 無論如何必須關閉連接
finally {
if (httpResponse != null) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
控制台輸出結果:
{"draw":1,"recordsTotal":1,"recordsFiltered":1,"data":[{"id":33,"created":1530542074000,"updated":1530542074000,"title":"ad1","subTitle":"ad1","titleDesc":"ad1","url":"https://sale.jd.com/act/XkCzhoisOMSW.html","pic":"https://m.360buyimg.com/babel/jfs/t20164/187/1771326168/92964/b42fade7/5b359ab2N93be3a65.jpg","pic2":"","content":"<p><br></p>","tbContentCategory":{"id":89,"created":null,"updated":null,"parent":null,"isParent":null,"name":"幻燈片","status":null,"sortOrder":null}}],"error":null}
創建 HttpPost 請求
案例代碼如下:
package com.cmcc.hello.httpclient;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
public class MyTest {
public static void main(String[] args) {
post();
}
private static void post() {
// 創建 HttpClient 客戶端
CloseableHttpClient httpClient = HttpClients.createDefault();
// 創建 HttpPost 請求
HttpPost httpPost = new HttpPost("http://localhost:8080/content/page");
// 設置長連接
httpPost.setHeader("Connection", "keep-alive");
// 設置代理(模擬瀏覽器版本)
httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
// 設置 Cookie
httpPost.setHeader("Cookie", "UM_distinctid=16442706a09352-0376059833914f-3c604504-1fa400-16442706a0b345; CNZZDATA1262458286=1603637673-1530123020-%7C1530123020; JSESSIONID=805587506F1594AE02DC45845A7216A4");
// 創建 HttpPost 參數
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("draw", "1"));
params.add(new BasicNameValuePair("start", "0"));
params.add(new BasicNameValuePair("length", "10"));
CloseableHttpResponse httpResponse = null;
try {
// 設置 HttpPost 參數
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
// 輸出請求結果
System.out.println(EntityUtils.toString(httpEntity));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 無論如何必須關閉連接
finally {
try {
if (httpResponse != null) {
httpResponse.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
控制台輸出結果:
{"draw":1,"recordsTotal":1,"recordsFiltered":1,"data":[{"id":33,"created":1530542074000,"updated":1530542074000,"title":"ad1","subTitle":"ad1","titleDesc":"ad1","url":"https://sale.jd.com/act/XkCzhoisOMSW.html","pic":"https://m.360buyimg.com/babel/jfs/t20164/187/1771326168/92964/b42fade7/5b359ab2N93be3a65.jpg","pic2":"","content":"<p><br></p>","tbContentCategory":{"id":89,"created":null,"updated":null,"parent":null,"isParent":null,"name":"幻燈片","status":null,"sortOrder":null}}],"error":null}
轉自:有夢想的咸魚