簡介
HttpClient是Apache Jakarta Common下的子項(xiàng)目薄料,用來提供高效的、最新的盆繁、功能豐富的支持HTTP協(xié)議的客戶端編程工具包秩铆,并且它支持HTTP協(xié)議最新的版本和建議。
HttpClient最新版本是HttpClient 4.5.3 (GA)曾棕。
官方下載:http://hc.apache.org/downloads.cgi
主要特性
- 基于標(biāo)準(zhǔn)扣猫、純凈的Java語言,實(shí)現(xiàn)了HTTP1.0和HTTP1.1翘地。
- 以可擴(kuò)展的面向?qū)ο蟮慕Y(jié)構(gòu)實(shí)現(xiàn)了HTTP全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)申尤。
- 支持加密的HTTPS協(xié)議(HTTP通過SSL協(xié)議)。
- 通過HTTP代理方式建立透明的連接衙耕。
- 利用CONNECT方法通過HTTP代理建立隧道的HTTPS連接昧穿。
- Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos認(rèn)證方案。
- 插件式的自定義認(rèn)證方案橙喘。
- 可插拔的安全套接字工廠时鸵,使得接入第三方解決方案變得更容易
- 連接管理支持使用多線程的的應(yīng)用。支持設(shè)置最大連接數(shù)厅瞎,同時(shí)支持設(shè)置每個(gè)主機(jī)的最大連接數(shù)饰潜,發(fā)現(xiàn)并關(guān)閉過期的連接初坠。
- 自動(dòng)化處理Set-Cookie:來自服務(wù)器的頭,并在適當(dāng)?shù)臅r(shí)候?qū)⑺鼈儼l(fā)送回cookie囊拜。
- 可以自定義Cookie策略的插件化機(jī)制某筐。
- Request的輸出流可以避免流中內(nèi)容體直接從socket緩沖到服務(wù)器。
- Response的輸入流可以有效的從socket服務(wù)器直接讀取相應(yīng)內(nèi)容冠跷。
- 在HTTP1.0和HTTP1.1中使用用KeepAlive來保持持久連接南誊。
- 可以直接獲取服務(wù)器發(fā)送的響應(yīng)碼和響應(yīng)頭部。
- 具備設(shè)置連接超時(shí)的能力蜜托。
- 支持HTTP/1.1 響應(yīng)緩存抄囚。
- 源代碼基于Apache License 可免費(fèi)獲取。
一般使用步驟
使用HttpClient發(fā)送請(qǐng)求橄务、接收響應(yīng)幔托,一般需要以下步驟。
HttpGet請(qǐng)求響應(yīng)的一般步驟:
1). 創(chuàng)建HttpClient
對(duì)象,可以使用HttpClients.createDefault()
蜂挪;
2). 如果是無參數(shù)的GET請(qǐng)求重挑,則直接使用構(gòu)造方法HttpGet(String url)
創(chuàng)建HttpGet
對(duì)象即可;
如果是帶參數(shù)GET請(qǐng)求棠涮,則可以先使用URIBuilder(String url)
創(chuàng)建對(duì)象谬哀,再調(diào)用addParameter(String param, String value)
,或setParameter(String param, String value)
來設(shè)置請(qǐng)求參數(shù)严肪,并調(diào)用build()方法構(gòu)建一個(gè)URI對(duì)象史煎。只有構(gòu)造方法HttpGet(URI uri)
來創(chuàng)建HttpGet對(duì)象。
3). 創(chuàng)建HttpResponse
驳糯,調(diào)用HttpClient
對(duì)象的execute(HttpUriRequest request)
發(fā)送請(qǐng)求篇梭,該方法返回一個(gè)HttpResponse
。調(diào)用HttpResponse
的getAllHeaders()酝枢、getHeaders(String name)
等方法可獲取服務(wù)器的響應(yīng)頭恬偷;調(diào)用HttpResponse
的getEntity()
方法可獲取HttpEntity對(duì)象,該對(duì)象包裝了服務(wù)器的響應(yīng)內(nèi)容帘睦。程序可通過該對(duì)象獲取服務(wù)器的響應(yīng)內(nèi)容袍患。通過調(diào)用getStatusLine().getStatusCode()
可以獲取響應(yīng)狀態(tài)碼。
4). 釋放連接官脓。
HttpPost請(qǐng)求響應(yīng)的一般步驟:
1). 創(chuàng)建HttpClient
對(duì)象,可以使用HttpClients.createDefault()
;
2). 如果是無參數(shù)的GET請(qǐng)求涝焙,則直接使用構(gòu)造方法HttpPost(String url)
創(chuàng)建HttpPost
對(duì)象即可卑笨;
如果是帶參數(shù)POST請(qǐng)求,先構(gòu)建HttpEntity對(duì)象并設(shè)置請(qǐng)求參數(shù)仑撞,然后調(diào)用setEntity(HttpEntity entity)創(chuàng)建HttpPost對(duì)象赤兴。
3). 創(chuàng)建HttpResponse
妖滔,調(diào)用HttpClient
對(duì)象的execute(HttpUriRequest request)
發(fā)送請(qǐng)求,該方法返回一個(gè)HttpResponse
桶良。調(diào)用HttpResponse
的getAllHeaders()座舍、getHeaders(String name)
等方法可獲取服務(wù)器的響應(yīng)頭;調(diào)用HttpResponse
的getEntity()
方法可獲取HttpEntity對(duì)象陨帆,該對(duì)象包裝了服務(wù)器的響應(yīng)內(nèi)容曲秉。程序可通過該對(duì)象獲取服務(wù)器的響應(yīng)內(nèi)容。通過調(diào)用getStatusLine().getStatusCode()
可以獲取響應(yīng)狀態(tài)碼疲牵。
4). 釋放連接承二。
實(shí)例代碼實(shí)戰(zhàn)
構(gòu)建一個(gè)Maven項(xiàng)目,引入如下依賴
<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>
實(shí)例1:普通的無參數(shù)GET請(qǐng)求
打開一個(gè)url纲爸,抓取響應(yīng)結(jié)果輸出成html文件
/**
*普通的GET請(qǐng)求
*/
public class DoGET {
public static void main(String[] args) throws Exception {
// 創(chuàng)建Httpclient對(duì)象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 創(chuàng)建http GET請(qǐng)求
HttpGet httpGet = new HttpGet("http://www.baidu.com");
CloseableHttpResponse response = null;
try {
// 執(zhí)行請(qǐng)求
response = httpclient.execute(httpGet);
// 判斷返回狀態(tài)是否為200
if (response.getStatusLine().getStatusCode() == 200) {
//請(qǐng)求體內(nèi)容
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//內(nèi)容寫入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\baidu.html"), content, "UTF-8");
System.out.println("內(nèi)容長度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
//相當(dāng)于關(guān)閉瀏覽器
httpclient.close();
}
}
}
實(shí)例2:執(zhí)行帶參數(shù)的GET請(qǐng)求
模擬使用百度搜索關(guān)鍵字"java",并保存搜索結(jié)果為html文件
import java.io.File;
import java.net.URI;
import org.apache.commons.io.FileUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* 帶參數(shù)的GET請(qǐng)求
* 兩種方式:
* 1.直接將參數(shù)拼接到url后面 如:?wd=java
* 2.使用URI的方法設(shè)置參數(shù) setParameter("wd", "java")
*/
public class DoGETParam {
public static void main(String[] args) throws Exception {
// 創(chuàng)建Httpclient對(duì)象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 定義請(qǐng)求的參數(shù)
URI uri = new URIBuilder("http://www.baidu.com/s").setParameter("wd", "java").build();
// 創(chuàng)建http GET請(qǐng)求
HttpGet httpGet = new HttpGet(uri);
//response 對(duì)象
CloseableHttpResponse response = null;
try {
// 執(zhí)行http get請(qǐng)求
response = httpclient.execute(httpGet);
// 判斷返回狀態(tài)是否為200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//內(nèi)容寫入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\baidu-param.html"), content, "UTF-8");
System.out.println("內(nèi)容長度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
}
實(shí)例3:執(zhí)行普通的POST請(qǐng)求
無參數(shù)的POST請(qǐng)求亥鸠,并設(shè)置Header來偽裝瀏覽器請(qǐng)求
import org.apache.commons.io.FileUtils;
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.util.EntityUtils;
import java.io.File;
/**
* 常規(guī)post請(qǐng)求
* 可以設(shè)置Header來偽裝瀏覽器請(qǐng)求
*/
public class DoPOST {
public static void main(String[] args) throws Exception {
// 創(chuàng)建Httpclient對(duì)象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 創(chuàng)建http POST請(qǐng)求
HttpPost httpPost = new HttpPost("http://www.oschina.net/");
//偽裝瀏覽器請(qǐng)求
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");
CloseableHttpResponse response = null;
try {
// 執(zhí)行請(qǐng)求
response = httpclient.execute(httpPost);
// 判斷返回狀態(tài)是否為200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//內(nèi)容寫入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\oschina.html"), content, "UTF-8");
System.out.println("內(nèi)容長度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
}
實(shí)例4:執(zhí)行帶參數(shù)的POST請(qǐng)求
模擬開源中國檢索java,并偽裝瀏覽器請(qǐng)求识啦,輸出響應(yīng)結(jié)果為html文件
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.http.NameValuePair;
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;
/**
* 帶有參數(shù)的Post請(qǐng)求
* NameValuePair
*/
public class DoPOSTParam {
public static void main(String[] args) throws Exception {
// 創(chuàng)建Httpclient對(duì)象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 創(chuàng)建http POST請(qǐng)求
HttpPost httpPost = new HttpPost("http://www.oschina.net/search");
// 設(shè)置2個(gè)post參數(shù)负蚊,一個(gè)是scope、一個(gè)是q
List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
parameters.add(new BasicNameValuePair("scope", "project"));
parameters.add(new BasicNameValuePair("q", "java"));
// 構(gòu)造一個(gè)form表單式的實(shí)體
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
// 將請(qǐng)求實(shí)體設(shè)置到httpPost對(duì)象中
httpPost.setEntity(formEntity);
//偽裝瀏覽器
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");
CloseableHttpResponse response = null;
try {
// 執(zhí)行請(qǐng)求
response = httpclient.execute(httpPost);
// 判斷返回狀態(tài)是否為200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//內(nèi)容寫入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\oschina-param.html"), content, "UTF-8");
System.out.println("內(nèi)容長度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
}
總結(jié)
本文介紹了HttpClient的特性颓哮,是按照官方英文文檔翻譯而來家妆,然后分別介紹了HttpGet和HttpPost的一般使用步驟,最后給出了4個(gè)簡單的實(shí)例的Java代碼题翻。下一章節(jié)我們會(huì)介紹HttpClient連接池管理以及Spring整合HttpClient的具體過程揩徊。