簡介
HttpClient是Apache Jakarta Common下的子項目,用來提供高效的、最新的、功能豐富的支持HTTP協議的客戶端編程工具包,並且它支持HTTP協議最新的版本和建議。
HttpClient最新版本是HttpClient 4.5.3 (GA)。
官方下載:http://hc.apache.org/downloads.cgi
主要特性
- 基於標准、純凈的Java語言,實現了HTTP1.0和HTTP1.1。
- 以可擴展的面向對象的結構實現了HTTP全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。
- 支持加密的HTTPS協議(HTTP通過SSL協議)。
- 通過HTTP代理方式建立透明的連接。
- 利用CONNECT方法通過HTTP代理建立隧道的HTTPS連接。
- Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos認證方案。
- 插件式的自定義認證方案。
- 可插拔的安全套接字工廠,使得接入第三方解決方案變得更容易
- 連接管理支持使用多線程的的應用。支持設置最大連接數,同時支持設置每個主機的最大連接數,發現並關閉過期的連接。
- 自動化處理Set-Cookie:來自服務器的頭,並在適當的時候將它們發送回cookie。
- 可以自定義Cookie策略的插件化機制。
- Request的輸出流可以避免流中內容體直接從socket緩沖到服務器。
- Response的輸入流可以有效的從socket服務器直接讀取相應內容。
- 在HTTP1.0和HTTP1.1中使用用KeepAlive來保持持久連接。
- 可以直接獲取服務器發送的響應碼和響應頭部。
- 具備設置連接超時的能力。
- 支持HTTP/1.1 響應緩存。
- 源代碼基於Apache License 可免費獲取。
一般使用步驟
使用HttpClient發送請求、接收響應,一般需要以下步驟。
HttpGet請求響應的一般步驟:
1). 創建HttpClient
對象,可以使用HttpClients.createDefault()
;
2). 如果是無參數的GET請求,則直接使用構造方法HttpGet(String url)
創建HttpGet
對象即可;
如果是帶參數GET請求,則可以先使用URIBuilder(String url)
創建對象,再調用addParameter(String param, String value)
,或setParameter(String param, String value)
來設置請求參數,並調用build()方法構建一個URI對象。只有構造方法HttpGet(URI uri)
來創建HttpGet對象。
3). 創建HttpResponse
,調用HttpClient
對象的execute(HttpUriRequest request)
發送請求,該方法返回一個HttpResponse
。調用HttpResponse
的getAllHeaders()、getHeaders(String name)
等方法可獲取服務器的響應頭;調用HttpResponse
的getEntity()
方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。通過調用getStatusLine().getStatusCode()
可以獲取響應狀態碼。
4). 釋放連接。
HttpPost請求響應的一般步驟:
1). 創建HttpClient
對象,可以使用HttpClients.createDefault()
;
2). 如果是無參數的GET請求,則直接使用構造方法HttpPost(String url)
創建HttpPost
對象即可;
如果是帶參數POST請求,先構建HttpEntity對象並設置請求參數,然后調用setEntity(HttpEntity entity)創建HttpPost對象。
3). 創建HttpResponse
,調用HttpClient
對象的execute(HttpUriRequest request)
發送請求,該方法返回一個HttpResponse
。調用HttpResponse
的getAllHeaders()、getHeaders(String name)
等方法可獲取服務器的響應頭;調用HttpResponse
的getEntity()
方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。通過調用getStatusLine().getStatusCode()
可以獲取響應狀態碼。
4). 釋放連接。
官方文檔中的示例
1 //1.獲得一個httpclient對象 2 CloseableHttpClient httpclient = HttpClients.createDefault(); 3 //2.生成一個get請求 4 HttpGet httpget = new HttpGet("http://localhost/"); 5 //3.執行get請求並返回結果 6 CloseableHttpResponse response = httpclient.execute(httpget); 7 try { 8 //4.處理結果 9 } finally { 10 response.close(); 11 }
實例代碼實戰
構建一個Maven項目,引入如下依賴
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency>
實例1:普通的無參數GET請求
打開一個url,抓取響應結果輸出成html文件
1 /** 2 *普通的GET請求 3 */ 4 public class DoGET { 5 public static void main(String[] args) throws Exception { 6 // 創建Httpclient對象 7 CloseableHttpClient httpclient = HttpClients.createDefault(); 8 // 創建http GET請求 9 HttpGet httpGet = new HttpGet("http://www.baidu.com"); 10 CloseableHttpResponse response = null; 11 try { 12 // 執行請求 13 response = httpclient.execute(httpGet); 14 // 判斷返回狀態是否為200 15 if (response.getStatusLine().getStatusCode() == 200) { 16 //請求體內容 17 String content = EntityUtils.toString(response.getEntity(), "UTF-8"); 18 //內容寫入文件 19 FileUtils.writeStringToFile(new File("E:\\devtest\\baidu.html"), content, "UTF-8"); 20 System.out.println("內容長度:"+content.length()); 21 } 22 } finally { 23 if (response != null) { 24 response.close(); 25 } 26 //相當於關閉瀏覽器 27 httpclient.close(); 28 } 29 } 30 }
實例2:執行帶參數的GET請求
模擬使用百度搜索關鍵字"java",並保存搜索結果為html文件
1 import java.io.File; 2 import java.net.URI; 3 import org.apache.commons.io.FileUtils; 4 import org.apache.http.client.methods.CloseableHttpResponse; 5 import org.apache.http.client.methods.HttpGet; 6 import org.apache.http.client.utils.URIBuilder; 7 import org.apache.http.impl.client.CloseableHttpClient; 8 import org.apache.http.impl.client.HttpClients; 9 import org.apache.http.util.EntityUtils; 10 /** 11 * 帶參數的GET請求 12 * 兩種方式: 13 * 1.直接將參數拼接到url后面 如:?wd=java 14 * 2.使用URI的方法設置參數 setParameter("wd", "java") 15 */ 16 public class DoGETParam { 17 public static void main(String[] args) throws Exception { 18 // 創建Httpclient對象 19 CloseableHttpClient httpclient = HttpClients.createDefault(); 20 // 定義請求的參數 21 URI uri = new URIBuilder("http://www.baidu.com/s").setParameter("wd", "java").build(); 22 // 創建http GET請求 23 HttpGet httpGet = new HttpGet(uri); 24 //response 對象 25 CloseableHttpResponse response = null; 26 try { 27 // 執行http get請求 28 response = httpclient.execute(httpGet); 29 // 判斷返回狀態是否為200 30 if (response.getStatusLine().getStatusCode() == 200) { 31 String content = EntityUtils.toString(response.getEntity(), "UTF-8"); 32 //內容寫入文件 33 FileUtils.writeStringToFile(new File("E:\\devtest\\baidu-param.html"), content, "UTF-8"); 34 System.out.println("內容長度:"+content.length()); 35 } 36 } finally { 37 if (response != null) { 38 response.close(); 39 } 40 httpclient.close(); 41 } 42 } 43 }
實例3:執行普通的POST請求
無參數的POST請求,並設置Header來偽裝瀏覽器請求
1 import org.apache.commons.io.FileUtils; 2 import org.apache.http.client.methods.CloseableHttpResponse; 3 import org.apache.http.client.methods.HttpPost; 4 import org.apache.http.impl.client.CloseableHttpClient; 5 import org.apache.http.impl.client.HttpClients; 6 import org.apache.http.util.EntityUtils; 7 8 import java.io.File; 9 10 /** 11 * 常規post請求 12 * 可以設置Header來偽裝瀏覽器請求 13 */ 14 public class DoPOST { 15 public static void main(String[] args) throws Exception { 16 // 創建Httpclient對象 17 CloseableHttpClient httpclient = HttpClients.createDefault(); 18 // 創建http POST請求 19 HttpPost httpPost = new HttpPost("http://www.oschina.net/"); 20 //偽裝瀏覽器請求 21 httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"); 22 CloseableHttpResponse response = null; 23 try { 24 // 執行請求 25 response = httpclient.execute(httpPost); 26 // 判斷返回狀態是否為200 27 if (response.getStatusLine().getStatusCode() == 200) { 28 String content = EntityUtils.toString(response.getEntity(), "UTF-8"); 29 //內容寫入文件 30 FileUtils.writeStringToFile(new File("E:\\devtest\\oschina.html"), content, "UTF-8"); 31 System.out.println("內容長度:"+content.length()); 32 } 33 } finally { 34 if (response != null) { 35 response.close(); 36 } 37 httpclient.close(); 38 } 39 } 40 }
實例4:執行帶參數的POST請求
模擬開源中國檢索java,並偽裝瀏覽器請求,輸出響應結果為html文件

1 import java.io.File; 2 import java.util.ArrayList; 3 import java.util.List; 4 5 import org.apache.commons.io.FileUtils; 6 import org.apache.http.NameValuePair; 7 import org.apache.http.client.entity.UrlEncodedFormEntity; 8 import org.apache.http.client.methods.CloseableHttpResponse; 9 import org.apache.http.client.methods.HttpPost; 10 import org.apache.http.impl.client.CloseableHttpClient; 11 import org.apache.http.impl.client.HttpClients; 12 import org.apache.http.message.BasicNameValuePair; 13 import org.apache.http.util.EntityUtils; 14 15 /** 16 * 帶有參數的Post請求 17 * NameValuePair 18 */ 19 public class DoPOSTParam { 20 public static void main(String[] args) throws Exception { 21 // 創建Httpclient對象 22 CloseableHttpClient httpclient = HttpClients.createDefault(); 23 // 創建http POST請求 24 HttpPost httpPost = new HttpPost("http://www.oschina.net/search"); 25 // 設置2個post參數,一個是scope、一個是q 26 List<NameValuePair> parameters = new ArrayList<NameValuePair>(0); 27 parameters.add(new BasicNameValuePair("scope", "project")); 28 parameters.add(new BasicNameValuePair("q", "java")); 29 // 構造一個form表單式的實體 30 UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters); 31 // 將請求實體設置到httpPost對象中 32 httpPost.setEntity(formEntity); 33 //偽裝瀏覽器 34 httpPost.setHeader("User-Agent", 35 "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"); 36 CloseableHttpResponse response = null; 37 try { 38 // 執行請求 39 response = httpclient.execute(httpPost); 40 // 判斷返回狀態是否為200 41 if (response.getStatusLine().getStatusCode() == 200) { 42 String content = EntityUtils.toString(response.getEntity(), "UTF-8"); 43 //內容寫入文件 44 FileUtils.writeStringToFile(new File("E:\\devtest\\oschina-param.html"), content, "UTF-8"); 45 System.out.println("內容長度:"+content.length()); 46 } 47 } finally { 48 if (response != null) { 49 response.close(); 50 } 51 httpclient.close(); 52 } 53 } 54 }
總結
本文介紹了HttpClient的特性,是按照官方英文文檔翻譯而來,然后分別介紹了HttpGet和HttpPost的一般使用步驟,最后給出了4個簡單的實例的Java代碼。下一章節我們會介紹HttpClient連接池管理以及Spring整合HttpClient的具體過程。