日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

httpclient 学习

發(fā)布時間:2025/3/14 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 httpclient 学习 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Http協(xié)議的重要性相信不用我多說了,HttpClient相比傳統(tǒng)JDK自帶的URLConnection,增加了易用性和靈活性,它不僅是客戶端發(fā)送Http請求變得容易,而且也方便了開發(fā)人員測試接口(基于Http協(xié)議的),即提高了開發(fā)的效率,也方便提高代碼的健壯性。因此熟練掌握HttpClient是很重要的必修內(nèi)容,掌握HttpClient后,相信對于Http協(xié)議的了解會更加深入。

一、簡介

HttpClient是Apache Jakarta Common下的子項目,用來提供高效的、最新的、功能豐富的支持HTTP協(xié)議的客戶端編程工具包,并且它支持HTTP協(xié)議最新的版本和建議。HttpClient已經(jīng)應(yīng)用在很多的項目中,比如Apache Jakarta上很著名的另外兩個開源項目Cactus和HTMLUnit都使用了HttpClient。

?

二、特性

1. 基于標(biāo)準(zhǔn)、純凈的Java語言。實現(xiàn)了Http1.0和Http1.1

2. 以可擴展的面向?qū)ο蟮慕Y(jié)構(gòu)實現(xiàn)了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。

3. 支持HTTPS協(xié)議。

4. 通過Http代理建立透明的連接。

5. 利用CONNECT方法通過Http代理建立隧道的https連接。

6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos認(rèn)證方案。

7. 插件式的自定義認(rèn)證方案。

8. 便攜可靠的套接字工廠使它更容易的使用第三方解決方案。

9. 連接管理器支持多線程應(yīng)用。支持設(shè)置最大連接數(shù),同時支持設(shè)置每個主機的最大連接數(shù),發(fā)現(xiàn)并關(guān)閉過期的連接。

10. 自動處理Set-Cookie中的Cookie。

11. 插件式的自定義Cookie策略。

12. Request的輸出流可以避免流中內(nèi)容直接緩沖到socket服務(wù)器。

13. Response的輸入流可以有效的從socket服務(wù)器直接讀取相應(yīng)內(nèi)容。

14. 在http1.0和http1.1中利用KeepAlive保持持久連接。

15. 直接獲取服務(wù)器發(fā)送的response code和 headers。

16. 設(shè)置連接超時的能力。

17. 實驗性的支持http1.1 response caching。

18. 源代碼基于Apache License 可免費獲取。

三、使用方法

使用HttpClient發(fā)送請求、接收響應(yīng)很簡單,一般需要如下幾步即可。

1.?創(chuàng)建HttpClient對象。

2.?創(chuàng)建請求方法的實例,并指定請求URL。如果需要發(fā)送GET請求,創(chuàng)建HttpGet對象;如果需要發(fā)送POST請求,創(chuàng)建HttpPost對象。

3.?如果需要發(fā)送請求參數(shù),可調(diào)用HttpGet、HttpPost共同的setParams(HetpParams params)方法來添加請求參數(shù);對于HttpPost對象而言,也可調(diào)用setEntity(HttpEntity entity)方法來設(shè)置請求參數(shù)。

4.?調(diào)用HttpClient對象的execute(HttpUriRequest request)發(fā)送請求,該方法返回一個HttpResponse。

5.?調(diào)用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務(wù)器的響應(yīng)頭;調(diào)用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務(wù)器的響應(yīng)內(nèi)容。程序可通過該對象獲取服務(wù)器的響應(yīng)內(nèi)容。

6.?釋放連接。無論執(zhí)行方法是否成功,都必須釋放連接

四、實例

實例一:模擬get請求發(fā)送,獲取返回的內(nèi)容。

package httpclient;import java.io.IOException;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;/*** Hello world!**/ public class App {public static void main( String[] args ) throws Exception, IOException{CloseableHttpClient httpclient = HttpClients.createDefault(); //創(chuàng)建httpclientHttpGet httpGet = new HttpGet("https://www.cnblogs.com"); //創(chuàng)建get 請求CloseableHttpResponse response = httpclient.execute(httpGet); //通過httpcleint 發(fā)送get 請求if(response != null){HttpEntity httpentity = response.getEntity(); //獲取響應(yīng)System.out.println(EntityUtils.toString(httpentity,"UTF-8")); //采用工具來將實體進行轉(zhuǎn)換輸出 }response.close();httpclient.close();} }

?

結(jié)果如下:

?

說明上面代碼采用的maven 項目需要導(dǎo)入httpclient相關(guān)的包,pom文件如下:

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>

總結(jié),上面我看看到httpclient 很容易的模擬了,客戶端發(fā)送了http請求,post方式方式一樣,但是接下來我們看下面的一個實例:

?

package httpclient;import java.io.IOException;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;/*** Hello world!**/ public class App {public static void main( String[] args ) throws Exception, IOException{CloseableHttpClient httpclient = HttpClients.createDefault(); //創(chuàng)建httpclientHttpGet httpGet = new HttpGet("http://www.tuicool.com/"); //創(chuàng)建get 請求CloseableHttpResponse response = httpclient.execute(httpGet); //通過httpcleint 發(fā)送get 請求if(response != null){HttpEntity httpentity = response.getEntity(); //獲取響應(yīng)System.out.println(EntityUtils.toString(httpentity,"UTF-8")); //采用工具來將實體進行轉(zhuǎn)換輸出 }response.close();httpclient.close();} }

?

結(jié)果如下:

?

?這是為什么呢? 原因就在于我們上面模擬的是客戶端發(fā)送了http請求,但不是模擬的瀏覽器發(fā)出的請求,因此有些網(wǎng)站做了防護,怎么來模擬瀏覽器發(fā)出的請求呢? 瀏覽器在請的過程中,我們知道會有請求頭信息,以便目標(biāo)服務(wù)器識別,如下:

?

?

?

會有一個:

  • Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
  • Accept-Encoding: gzip, deflate
  • Accept-Language: zh-CN,zh;q=0.8
  • Cache-Control: max-age=0
  • Connection: keep-alive
  • Cookie: _tuicool_session=BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJWE5MWZjYzMwMDBmYjRjZWJjZWI5ZmE1MWNlNzQwNzQ4BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMXpvZzZRVEVLNHNEYlJNYVJqMVlrUG5tUHJWR0FaeDh0RzFxY28za3pzR009BjsARkkiDnJldHVybl90bwY7AEZJIitodHRwOi8vd3d3LnR1aWNvb2wuY29tL2FydGljbGVzL2JRajJFMwY7AEY%3D--d83358350fdbe214e013c16660630e5ffa3fc4f0; UM_distinctid=15e47ec08fe321-044bcb8a12f122-546b3971-100200-15e47ec08ff33c; CNZZDATA5541078=cnzz_eid%3D626609411-1504443418-%26ntime%3D1504443418
  • Host: www.tuicool.com
  • If-None-Match: W/"a415838fed502ea413339b0b13542108"
  • Upgrade-Insecure-Requests: 1
  • User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
  • 其中最重要的是就是User-Agent,那么我們要模擬瀏覽器,則需要設(shè)置頭消息,代碼如下:

    package httpclient;import java.io.IOException;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;/*** Hello world!**/ public class App {public static void main( String[] args ) throws Exception, IOException{CloseableHttpClient httpclient = HttpClients.createDefault(); //創(chuàng)建httpclientHttpGet httpGet = new HttpGet("http://www.tuicool.com/"); //創(chuàng)建get 請求httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");CloseableHttpResponse response = httpclient.execute(httpGet); //通過httpcleint 發(fā)送get 請求if(response != null){HttpEntity httpentity = response.getEntity(); //獲取響應(yīng)System.out.println(EntityUtils.toString(httpentity,"UTF-8")); //采用工具來將實體進行轉(zhuǎn)換輸出 }response.close();httpclient.close();} }

    ?

    這個時候,我們測試一下可以看到結(jié)果如下:

    ?

    結(jié)果已經(jīng)正常顯示出來了,但這個時候,我們是否想到,既然一個瀏覽器發(fā)送了http請求,我們會看到有狀態(tài),那么如何通過httpclient返回的response來獲取對應(yīng)的狀態(tài)呢,以及如何獲取響應(yīng)的類型呢?類型即我們說的content-type

    ?

    這個時候我們需要通過HttpEntity 來獲取,為什么獲取content-type 是因為獲取的類型非常多,有些是不需要我們采集的,這個時候我們可以通過這個內(nèi)容類型進行采集過濾。

    代碼如下:

    package httpclient;import java.io.IOException;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;/*** Hello world!**/ public class App {public static void main( String[] args ) throws Exception, IOException{CloseableHttpClient httpclient = HttpClients.createDefault(); //創(chuàng)建httpclientHttpGet httpGet = new HttpGet("http://www.tuicool.com/"); //創(chuàng)建get 請求httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");CloseableHttpResponse response = httpclient.execute(httpGet); //通過httpcleint 發(fā)送get 請求if(response != null){System.out.println(response.getStatusLine().getStatusCode());HttpEntity httpentity = response.getEntity(); //獲取響應(yīng) System.out.println(httpentity.getContentType().getValue());//System.out.println(EntityUtils.toString(httpentity,"UTF-8")); //采用工具來將實體進行轉(zhuǎn)換輸出 }response.close();httpclient.close();} }

    結(jié)果如下:

    ?

    總結(jié),上面我們采取的都靜態(tài)的文本等,但是我們采集的時候,如果要采集圖片怎么辦,圖片的獲取處理方式如下:

    比如:http://aimg2.tuicool.com/qm6Rre6.jpg!index ?采集這個圖片。

    ?

    package httpclient;import java.io.File; import java.io.IOException; import java.io.InputStream;import org.apache.commons.io.FileUtils; 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;/*** Hello world!**/ public class App {public static void main( String[] args ) throws Exception, IOException{CloseableHttpClient httpclient = HttpClients.createDefault(); //創(chuàng)建httpclientHttpGet httpGet = new HttpGet("http://aimg2.tuicool.com/qm6Rre6.jpg!index"); //創(chuàng)建get 請求httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");CloseableHttpResponse response = httpclient.execute(httpGet); //通過httpcleint 發(fā)送get 請求if(response != null){//System.out.println(response.getStatusLine().getStatusCode());HttpEntity httpentity = response.getEntity(); //獲取響應(yīng)if(httpentity != null){System.out.println(httpentity.getContentType().getValue()); //判斷內(nèi)容的類型,因為我們要采集圖片,所以要過濾掉其它內(nèi)容.//接著,圖片肯定要通過流的方式去讀取.InputStream inputStream = httpentity.getContent();//然后通過輸入流,然后讀取流,輸出流,則可以轉(zhuǎn)換讀取我們的圖片,流的復(fù)制.//在這里我們可以 通過Apache 提供的IO 工具流來直接進行流的復(fù)制.FileUtils.copyToFile(inputStream, new File("D://a.jpg")); //實際中是要拷貝真是的目錄下面,并且圖片的名稱也是唯一的。 }//System.out.println(httpentity.getContentType().getValue());//System.out.println(EntityUtils.toString(httpentity,"UTF-8")); //采用工具來將實體進行轉(zhuǎn)換輸出 }response.close();httpclient.close();} }

    ?

    注意上面,需要導(dǎo)入io 包。

    https://mvnrepository.com/artifact/commons-io/commons-io/2.5

    <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
    </dependency>

    ?

    ?

    實例二 :上面我們演示了,圖片的采集,和靜態(tài)信息的采集,但是對于一些有防范的網(wǎng)站,一般大公司會有屏蔽信,即不讓你長時間采集,一旦你長時間采集,則會進行封掉IP,那這個時候我們該怎么辦,這個時候我們需要代碼IP,先看下面的介紹:

    在爬取網(wǎng)頁的時候,有的目標(biāo)站點有反爬蟲機制,對于頻繁訪問站點以及規(guī)則性訪問站點的行為,會采集屏蔽IP措施。

    ?

    這時候,代理IP就派上用場了。

    ?

    關(guān)于代理IP的話 也分幾種?透明代理、匿名代理、混淆代理、高匿代理

    ?

    1、透明代理(Transparent Proxy)

    ?

    REMOTE_ADDR = Proxy IP

    ?

    HTTP_VIA = Proxy IP

    ?

    HTTP_X_FORWARDED_FOR = Your IP

    ?

    透明代理雖然可以直接“隱藏”你的IP地址,但是還是可以從HTTP_X_FORWARDED_FOR來查到你是誰。

    ?

    2、匿名代理(Anonymous Proxy)

    ?

    REMOTE_ADDR = proxy IP

    ?

    HTTP_VIA = proxy IP

    ?

    HTTP_X_FORWARDED_FOR = proxy IP

    ?

    匿名代理比透明代理進步了一點:別人只能知道你用了代理,無法知道你是誰。

    ?

    還有一種比純匿名代理更先進一點的:混淆代理,見下節(jié)。

    ?

    3、混淆代理(Distorting Proxies)

    ?

    REMOTE_ADDR = Proxy IP

    HTTP_VIA = Proxy IP

    HTTP_X_FORWARDED_FOR = Random IP address

    ?

    如上,與匿名代理相同,如果使用了混淆代理,別人還是能知道你在用代理,但是會得到一個假的IP地址,偽裝的更逼真:-)

    ?

    4、高匿代理(Elite proxy或High Anonymity Proxy)

    ?

    REMOTE_ADDR = Proxy IP

    ?

    HTTP_VIA = not determined

    ?

    HTTP_X_FORWARDED_FOR = not determined

    ?

    可以看出來,高匿代理讓別人根本無法發(fā)現(xiàn)你是在用代理,所以是最好的選擇。

    ?

    一般我們搞爬蟲 用的都是 高匿的代理IP;

    ?

    那代理IP 從哪里搞呢 很簡單 ?百度一下,你就知道 一大堆代理IP站點。 ?一般都會給出一些免費的,但是花點錢搞收費接口更加方便;

    ?

    比如?http://www.66ip.cn/

    ?

    httpClient使用代理IP代碼:

    package httpclient;import java.io.IOException;import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; 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;/*** Hello world!**/ public class App {public static void main( String[] args ) throws Exception, IOException{CloseableHttpClient httpclient = HttpClients.createDefault(); //創(chuàng)建httpclientHttpGet httpGet = new HttpGet("https://www.taobao.com/"); //創(chuàng)建get 請求HttpHost proxy = new HttpHost("115.202.167.56",808);RequestConfig config = RequestConfig.custom().setProxy(proxy).build();//設(shè)置代理IP httpGet.setConfig(config);httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");CloseableHttpResponse response = httpclient.execute(httpGet); //通過httpcleint 發(fā)送get 請求if(response != null){//System.out.println(response.getStatusLine().getStatusCode());HttpEntity httpentity = response.getEntity(); //獲取響應(yīng)if(httpentity != null){System.out.println(httpentity.getContentType().getValue());System.out.println(EntityUtils.toString(httpentity,"UTF-8")); //采用工具來將實體進行轉(zhuǎn)換輸出//System.out.println(httpentity.getContentType().getValue()); //判斷內(nèi)容的類型,因為我們要采集圖片,所以要過濾掉其它內(nèi)容.//接著,圖片肯定要通過流的方式去讀取.//InputStream inputStream = httpentity.getContent();//然后通過輸入流,然后讀取流,輸出流,則可以轉(zhuǎn)換讀取我們的圖片,流的復(fù)制.//在這里我們可以 通過Apache 提供的IO 工具流來直接進行流的復(fù)制.//FileUtils.copyToFile(inputStream, new File("D://a.jpg")); //實際中是要拷貝真是的目錄下面,并且圖片的名稱也是唯一的。 }//System.out.println(httpentity.getContentType().getValue());//System.out.println(EntityUtils.toString(httpentity,"UTF-8")); //采用工具來將實體進行轉(zhuǎn)換輸出 }response.close();httpclient.close();} }

    ?

    通過代理IP,測試結(jié)果如下:

    ?

    其它知識點:

    如連接超時時間設(shè)置,讀取內(nèi)容超時時間設(shè)置等。

    ?

    實例三:連接超時和內(nèi)容超時

    httpClient在執(zhí)行具體http請求時候 有一個連接的時間和讀取內(nèi)容的時間;

    HttpClient連接時間

    所謂連接的時候 是HttpClient發(fā)送請求的地方開始到連接上目標(biāo)url主機地址的時間,理論上是距離越短越快,

    線路越通暢越快,但是由于路由復(fù)雜交錯,往往連接上的時間都不固定,運氣不好連不上,HttpClient的默認(rèn)連接時間,據(jù)我測試,

    默認(rèn)是1分鐘,假如超過1分鐘 過一會繼續(xù)嘗試連接,這樣會有一個問題 假如遇到一個url老是連不上,會影響其他線程的線程進去,說難聽點,

    就是蹲著茅坑不拉屎。所以我們有必要進行特殊設(shè)置,比如設(shè)置10秒鐘 假如10秒鐘沒有連接上 我們就報錯,這樣我們就可以進行業(yè)務(wù)上的處理,

    比如我們業(yè)務(wù)上控制 過會再連接試試看。并且這個特殊url寫到log4j日志里去。方便管理員查看。

    HttpClient讀取時間

    所謂讀取的時間 是HttpClient已經(jīng)連接到了目標(biāo)服務(wù)器,然后進行內(nèi)容數(shù)據(jù)的獲取,一般情況 讀取數(shù)據(jù)都是很快速的,

    但是假如讀取的數(shù)據(jù)量大,或者是目標(biāo)服務(wù)器本身的問題(比如讀取數(shù)據(jù)庫速度慢,并發(fā)量大等等..)也會影響讀取時間。

    同上,我們還是需要來特殊設(shè)置下,比如設(shè)置10秒鐘 假如10秒鐘還沒讀取完,就報錯,同上,我們可以業(yè)務(wù)上處理。

    ?

    HttpClient給我們提供了一個RequestConfig類 專門用于配置參數(shù)比如連接時間,讀取時間以及前面講解的代理IP等。

    主要通過:

    RequestConfig config=RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(5000).build();httpGet.setConfig(config);

    ?

    ?到此,httpclient 相關(guān)的一些基本知識就學(xué)到這里了,如果深入學(xué)習(xí),可以參考httpclient的書籍深入.

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/pony1223/p/7471464.html

    總結(jié)

    以上是生活随笔為你收集整理的httpclient 学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。