最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

HttpClient基礎(chǔ)解析

 更新時(shí)間:2017年09月12日 14:46:54   作者:回眸一笑百媚生  
這篇文章主要介紹了HttpClient基礎(chǔ)知識(shí),算是比較詳細(xì)地對(duì)知識(shí)點(diǎn)和相關(guān)實(shí)例進(jìn)行解釋,需要的朋友可以參考下

本文講述了HttpClient基礎(chǔ)知識(shí),對(duì)相關(guān)概念進(jìn)行解釋在這里分享給大家,供大家參考。

1. 請(qǐng)求執(zhí)行:

HttpClient最重要的功能是執(zhí)行HTTP方法。執(zhí)行HTTP方法涉及一個(gè)或多個(gè)HTTP請(qǐng)求/ HTTP響應(yīng)交換,通常由HttpClient內(nèi)部處理。用戶期望提供一個(gè)請(qǐng)求對(duì)象來(lái)執(zhí)行,并且希望HttpClient將請(qǐng)求發(fā)送到目標(biāo)服務(wù)器返回相應(yīng)的響應(yīng)對(duì)象,如果執(zhí)行失敗則拋出異常。

很自然,HttpClient API的主要入口點(diǎn)是定義上述合同的HttpClient接口。

這是一個(gè)請(qǐng)求執(zhí)行過(guò)程的一個(gè)例子,它的最簡(jiǎn)單的形式是:

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("https://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
 <...>
} finally {
 response.close();
}

1.1. HTTP請(qǐng)求

所有HTTP請(qǐng)求都有一個(gè)請(qǐng)求行,包括方法名稱,請(qǐng)求URI和HTTP協(xié)議版本。

HttpClient的支持了在HTTP / 1.1規(guī)范中定義的所有HTTP方法的框的:GET,HEAD, POST,PUT,DELETE, TRACE和OPTIONS。沒(méi)有為每個(gè)方法類型:一個(gè)特定的類HttpGet, HttpHead,HttpPost, HttpPut,HttpDelete, HttpTrace,和HttpOptions。

Request-URI是統(tǒng)一資源標(biāo)識(shí)符,用于標(biāo)識(shí)應(yīng)用請(qǐng)求的資源。HTTP請(qǐng)求URI由協(xié)議方案,主機(jī)名,可選端口,資源路徑,可選查詢和可選片段組成。

URI uri = new URIBuilder()
  .setScheme("http")
  .setHost("www.google.com")
  .setPath("/search")
  .setParameter("q", "httpclient")
  .setParameter("btnG", "Google Search")
  .setParameter("aq", "f")
  .setParameter("oq", "")
  .build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());

1.2. HTTP響應(yīng)

HTTP響應(yīng)是在接收和解釋請(qǐng)求消息之后由服務(wù)器發(fā)送回客戶端的消息。該消息的第一行包括協(xié)議版本,后跟數(shù)字狀態(tài)代碼及其關(guān)聯(lián)的文本短語(yǔ)。

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
HttpStatus.SC_OK, "OK");
 
System.out.println(response.getProtocolVersion());
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(response.getStatusLine().getReasonPhrase());
System.out.println(response.getStatusLine().toString());
//輸出結(jié)果
/*
HTTP/1.1
200
OK
HTTP/1.1 200 OK
*/

1.3. 處理消息頭

HTTP消息可以包含描述消息屬性的多個(gè)頭部,如內(nèi)容長(zhǎng)度,內(nèi)容類型等。HttpClient提供了檢索,添加,刪除和枚舉頭文件的方法。
獲取給定類型的所有標(biāo)頭的最有效的方法是使用 HeaderIterator接口。

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,HttpStatus.SC_OK 
 ,"OK"); 
response.addHeader("Set-Cookie",
 "c1 = a; path = /; domain = localhost"); 
response.addHeader("Set-Cookie",
 "c2 = b; path = \"/ \",c3 = c; domain = \"localhost \""); 
 
HeaderIterator it = response.headerIterator("Set-Cookie"); 
 
while(it.hasNext()){ 
 System.out.println(it.next()); 
}

它還提供了方便的方法來(lái)將HTTP消息解析為單獨(dú)的頭元素。

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,HttpStatus.SC_OK 
 ,"OK"); 
response.addHeader("Set-Cookie",
 "c1 = a; path = /; domain = localhost"); 
response.addHeader("Set-Cookie",
 "c2 = b; path = \"/ \",c3 = c; domain = \"localhost \""); 
HeaderElementIterator it = new BasicHeaderElementIterator(
 response.headerIterator("Set-Cookie")); 
while(it.hasNext()){ 
 HeaderElement elem = it.nextElement(); 
 System.out.println(elem.getName()+"="+ elem.getValue()); 
 NameValuePair [] params = elem.getParameters(); 
 for(int i = 0; i <params.length; i ++){ 
  System.out。println(""+ params [i]); 
 } 
}

1.4. HTTP實(shí)體

HTTP消息可以攜帶與請(qǐng)求或響應(yīng)相關(guān)聯(lián)的內(nèi)容實(shí)體。實(shí)體可以在一些請(qǐng)求和一些響應(yīng)中找到,因?yàn)樗鼈兪强蛇x的。使用實(shí)體的請(qǐng)求被稱為實(shí)體封裝請(qǐng)求。HTTP規(guī)范定義了兩個(gè)實(shí)體封裝請(qǐng)求方法:POST和 PUT。響應(yīng)通常期望包含內(nèi)容實(shí)體。有例外的情況,如應(yīng)對(duì) HEAD方法204 No Content, 304 Not Modified,205 Reset Content 響應(yīng)。

HttpClient根據(jù)其內(nèi)容來(lái)源區(qū)分三種實(shí)體:

streamed: 內(nèi)容是從流中接收的,或者即時(shí)生成的。特別地,該類別包括從HTTP響應(yīng)接收到的實(shí)體。流式實(shí)體通常不可重復(fù)。

self-contained: 內(nèi)容在內(nèi)存中或通過(guò)獨(dú)立于連接或其他實(shí)體的方式獲取。自包含的實(shí)體通常是可重復(fù)的。這種類型的實(shí)體將主要用于封閉HTTP請(qǐng)求的實(shí)體。

wrapping: 內(nèi)容是從另一個(gè)實(shí)體獲得的。

當(dāng)從HTTP響應(yīng)流出內(nèi)容時(shí),此區(qū)別對(duì)于連接管理很重要。對(duì)于由應(yīng)用程序創(chuàng)建并且僅使用HttpClient發(fā)送的請(qǐng)求實(shí)體,流和獨(dú)立的區(qū)別不重要。在這種情況下,建議將不可重復(fù)的實(shí)體視為流式傳輸,將可重復(fù)的實(shí)體視為獨(dú)立的。

1.4.1. 可重復(fù)的實(shí)體

實(shí)體可以是可重復(fù)的,這意味著它的內(nèi)容可以被讀取不止一次。這是唯一可能的自包含的實(shí)體(像 ByteArrayEntity或 StringEntity)

1.4.2. 使用HTTP實(shí)體

由于實(shí)體可以表示二進(jìn)制和字符內(nèi)容,它支持字符編碼(以支持后者,即字符內(nèi)容)。

當(dāng)執(zhí)行帶有封閉內(nèi)容的請(qǐng)求時(shí),或者當(dāng)請(qǐng)求成功并且使用響應(yīng)主體將結(jié)果發(fā)送回客戶端時(shí),實(shí)體被創(chuàng)建。

要從實(shí)體讀取內(nèi)容,可以通過(guò)HttpEntity.getContent()方法來(lái)檢索輸入流,該方法返回一個(gè)java.io.InputStream,或者可以向HttpEntity.writeTo(OutputStream)方法提供輸出流,一旦所有內(nèi)容已寫(xiě)入給定流,該方法將返回。

當(dāng)實(shí)體已經(jīng)接收到傳入消息時(shí),方法 HttpEntity.getContentType()和 HttpEntity.getContentLength()方法可用于讀取公共元數(shù)據(jù),如頭Content-Type和 Content-Length頭(如果可用)。由于 Content-Type標(biāo)題可以包含text / plain或text / html等文本MIME類型的字符編碼,因此該 HttpEntity.getContentEncoding()方法用于讀取此信息。如果標(biāo)題不可用,則返回長(zhǎng)度為-1,內(nèi)容類型為NULL。如果Content-Type 標(biāo)題可用,Header將返回一個(gè)對(duì)象。

當(dāng)為外發(fā)消息創(chuàng)建實(shí)體時(shí),該元數(shù)據(jù)必須由實(shí)體的創(chuàng)建者提供。

StringEntity myEntity = new StringEntity("important message", 
 ContentType.create("text/plain", "UTF-8"));
System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);

1.5. 確保發(fā)布低級(jí)別資源

為了確保系統(tǒng)資源的正確釋放,必須關(guān)閉與實(shí)體或響應(yīng)本身相關(guān)聯(lián)的內(nèi)容流

CloseableHttpClient httpclient = HttpClients.createDefault(); 
HttpGet httpget = new HttpGet("http:// localhost /"); 
CloseableHttpResponse response = httpclient.execute(httpget); 
try{ 
 HttpEntity entity = response.getEntity(); 
 if(entity!= null){ 
  InputStream instream = entity.getContent(); 
  try{ 
   //做一些有用的事情
  } finally { 
   instream.close(); 
  } 
 } 
} finally { 
 response.close(); 
}

關(guān)閉內(nèi)容流和關(guān)閉響應(yīng)之間的區(qū)別在于,前者將嘗試通過(guò)占用實(shí)體內(nèi)容來(lái)保持底層連接,而后者會(huì)立即關(guān)閉并放棄連接。
請(qǐng)注意,HttpEntity.writeTo(OutputStream) 一旦實(shí)體完全寫(xiě)出,還需要確保正確釋放系統(tǒng)資源的方法。如果此方法獲取一個(gè)java.io.InputStream通過(guò)調(diào)用 的實(shí)例 HttpEntity.getContent(),那么也希望在finally子句中關(guān)閉流。

當(dāng)使用流實(shí)體時(shí),可以使用該 EntityUtils.consume(HttpEntity)方法來(lái)確保實(shí)體內(nèi)容已被完全消耗,底層流已經(jīng)被關(guān)閉。

然而,可能會(huì)有情況,當(dāng)只需要檢索整個(gè)響應(yīng)內(nèi)容的一小部分時(shí),消耗剩余內(nèi)容并使連接可重用的性能損失太高,在這種情況下,可以通過(guò)關(guān)閉終止內(nèi)容流響應(yīng)。

CloseableHttpClient httpclient = HttpClients.createDefault(); 
HttpGet httpget = new HttpGet("http:// localhost /"); 
CloseableHttpResponse response = httpclient.execute(httpget); 
try{ 
 HttpEntity entity = response.getEntity(); 
 if(entity!= null){ 
  InputStream instream = entity.getContent(); 
  int byteOne = instream.read(); 
  int byteTwo = instream.read(); 
  //不需要休息
 } 
} finally { 
 response.close(); 
}

連接不會(huì)重復(fù)使用,但由其持有的所有級(jí)別資源將被正確地分配。

1.6. 消費(fèi)實(shí)體內(nèi)容

消費(fèi)實(shí)體內(nèi)容的推薦方法是使用它 HttpEntity.getContent()或 HttpEntity.writeTo(OutputStream)方法。HttpClient還附帶了EntityUtils類,它暴露了幾種靜態(tài)方法,以便更容易地從實(shí)體讀取內(nèi)容或信息。java.io.InputStream可以使用這個(gè)類的方法,而不是直接讀取,而不是直接讀取字符串/字節(jié)數(shù)組中的整個(gè)內(nèi)容正文。但是,EntityUtils除非響應(yīng)實(shí)體來(lái)自可信HTTP服務(wù)器,而且已知其長(zhǎng)度有限,否則強(qiáng)烈建議不要使用此功能。

CloseableHttpClient httpclient = HttpClients.createDefault(); 
HttpGet httpget = new HttpGet("http:// localhost /"); 
CloseableHttpResponse response = httpclient.execute(httpget); 
try{ 
 HttpEntity entity = response.getEntity(); 
 if(entity!= null){ 
  long len = entity.getContentLength(); 
  if(len!= -1 && len <2048){ 
   System.out.println(EntityUtils.toString(entity)); 
  } else { 
   // Stream content out 
  } 
 } 
} finally { 
 response.close(); 
}

在某些情況下,可能需要多次讀取實(shí)體內(nèi)容。在這種情況下,實(shí)體內(nèi)容必須以某種方式緩存,無(wú)論是在內(nèi)存還是在磁盤上。最簡(jiǎn)單的方法是通過(guò)用BufferedHttpEntity類包裝原始實(shí)體。這將導(dǎo)致將原始實(shí)體的內(nèi)容讀入內(nèi)存緩沖區(qū)。在所有其他方面,實(shí)體包裝器將具有原始包裝器。

CloseableHttpResponse response = <...> 
HttpEntity entity = response.getEntity(); 
if(entity!= null){ 
 entity = new BufferedHttpEntity(entity); 
}

1.7. 制作實(shí)體內(nèi)容

HttpClient提供了幾個(gè)類,可以通過(guò)HTTP連接高效地流出內(nèi)容。這些類的實(shí)例可以與實(shí)體包圍請(qǐng)求,如相關(guān)聯(lián)POST并PUT 以包圍實(shí)體內(nèi)容分成傳出HTTP請(qǐng)求。HttpClient的提供了幾個(gè)類為最常見(jiàn)的數(shù)據(jù)的容器,如字符串,字節(jié)數(shù)組,輸入流,和文件:StringEntity, ByteArrayEntity, InputStreamEntity,和 FileEntity。

File file = new File("somefile.txt"); 
FileEntity entity = new FileEntity(file,
 ContentType.create("text / plain","UTF-8"));  
HttpPost httppost = new HttpPost("http://localhost/action.do"); 
httppost.setEntity(entity);

1.7.1 HTML表單
許多應(yīng)用程序需要模擬提交HTML表單的過(guò)程,例如,以登錄到Web應(yīng)用程序或提交輸入數(shù)據(jù)。HttpClient提供實(shí)體類 UrlEncodedFormEntity來(lái)促進(jìn)進(jìn)程。

List <NameValuePair> formparams = new ArrayList <NameValuePair>(); 
formparams.add(new BasicNameValuePair("param1","value1")); 
formparams.add(new BasicNameValuePair("param2","value2")); 
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams,Consts.UTF_8); 
HttpPost httppost = new HttpPost("http://localhost/handler.do"); 
httppost.setEntity(entity);

該UrlEncodedFormEntity實(shí)例將使用所謂的URL編碼來(lái)對(duì)參數(shù)進(jìn)行編碼并產(chǎn)生以下內(nèi)容:

param1=value1&param2=value2

1.7.2. 內(nèi)容分塊

一般建議讓HttpClient根據(jù)正在傳輸?shù)腍TTP消息的屬性選擇最合適的傳輸編碼。然而,可以通知HttpClient,通過(guò)設(shè)置HttpEntity.setChunked()為true,優(yōu)先選擇塊編碼。請(qǐng)注意,HttpClient只會(huì)使用此標(biāo)志作為提示。當(dāng)使用不支持塊編碼的HTTP協(xié)議版本(如HTTP / 1.0)時(shí),此值將被忽略。

StringEntity entity = new StringEntity("important message",
  ContentType.create("plain / text",Consts.UTF_8)); 
entity.setChunked(true); 
HttpPost httppost = new HttpPost("http://localhost/acrtion.do"); 
httppost.setEntity(entity);

1.8. 響應(yīng)處理程序

處理響應(yīng)的最簡(jiǎn)單和最方便的方法是使用ResponseHandler包含該handleResponse(HttpResponse response)方法的界面。這種方法完全可以緩解用戶不必?fù)?dān)心連接管理。使用ResponseHandlerHttpClient 時(shí) ,無(wú)論請(qǐng)求執(zhí)行是成功還是導(dǎo)致異常,HttpClient都會(huì)自動(dòng)保證將連接釋放回連接管理器。

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/json");
ResponseHandler<MyJsonObject> rh = new ResponseHandler<MyJsonObject>() {
 @Override
 public JsonObject handleResponse(
   final HttpResponse response) throws IOException {
  StatusLine statusLine = response.getStatusLine();
  HttpEntity entity = response.getEntity();
  if (statusLine.getStatusCode() >= 300) {
   throw new HttpResponseException(
     statusLine.getStatusCode(),
     statusLine.getReasonPhrase());
  }
  if (entity == null) {
   throw new ClientProtocolException("Response contains no content");
  }
  Gson gson = new GsonBuilder().create();
  ContentType contentType = ContentType.getOrDefault(entity);
  Charset charset = contentType.getCharset();
  Reader reader = new InputStreamReader(entity.getContent(), charset);
  return gson.fromJson(reader, MyJsonObject.class);
 }
};
MyJsonObject myjson = client.execute(httpget, rh);

總結(jié)

以上是本文對(duì)HttpClient基礎(chǔ)知識(shí)的全部介紹,希望對(duì)大家有所幫助。

相關(guān)文章

  • Java用20行代碼實(shí)現(xiàn)抖音小視頻批量轉(zhuǎn)換為gif動(dòng)態(tài)圖

    Java用20行代碼實(shí)現(xiàn)抖音小視頻批量轉(zhuǎn)換為gif動(dòng)態(tài)圖

    這篇文章主要介紹了Java用20行代碼實(shí)現(xiàn)抖音小視頻批量轉(zhuǎn)換為gif動(dòng)態(tài)圖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 如何使用會(huì)話Cookie和Java實(shí)現(xiàn)JWT身份驗(yàn)證

    如何使用會(huì)話Cookie和Java實(shí)現(xiàn)JWT身份驗(yàn)證

    這篇文章主要介紹了如何使用會(huì)話Cookie和Java實(shí)現(xiàn)JWT身份驗(yàn)證,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-03-03
  • 使用restTemplate.postForEntity()的問(wèn)題

    使用restTemplate.postForEntity()的問(wèn)題

    這篇文章主要介紹了使用restTemplate.postForEntity()的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析

    Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析

    這篇文章主要介紹了Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • Springboot集成GraphicsMagick

    Springboot集成GraphicsMagick

    本文主要是教大家如何將GraphicsMagick命令行工具集成到Springboot項(xiàng)目中,便可以使用Java進(jìn)行圖片處理相關(guān)開(kāi)發(fā)。
    2021-05-05
  • SpringBoot響應(yīng)Json數(shù)據(jù)亂碼通過(guò)配置的解決

    SpringBoot響應(yīng)Json數(shù)據(jù)亂碼通過(guò)配置的解決

    這篇文章主要介紹了SpringBoot響應(yīng)Json數(shù)據(jù)亂碼通過(guò)配置的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java字符串中${}或者{}等的占位符替換工具類

    java字符串中${}或者{}等的占位符替換工具類

    今天小編就為大家分享一篇關(guān)于java字符串中${}或者{}等的占位符替換工具類,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • Java多線程中常見(jiàn)的幾個(gè)問(wèn)題

    Java多線程中常見(jiàn)的幾個(gè)問(wèn)題

    這篇文章主要介紹了Java多線程中常見(jiàn)的幾個(gè)問(wèn)題 ,需要的朋友可以參考下
    2015-05-05
  • 快速入門HarmonyOS的Java UI框架的教程

    快速入門HarmonyOS的Java UI框架的教程

    這篇文章主要介紹了快速入門HarmonyOS的Java UI框架,本文給大家介紹的非常詳細(xì)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot中事務(wù)的只讀屬性詳解

    SpringBoot中事務(wù)的只讀屬性詳解

    這篇文章主要介紹了SpringBoot中事務(wù)的只讀屬性詳解,在開(kāi)發(fā)過(guò)程中,事務(wù)是一個(gè)非常重要的概念,在?Spring?Boot中,事務(wù)是通過(guò)?AOP?機(jī)制來(lái)實(shí)現(xiàn)的,可以很方便地進(jìn)行管理,需要的朋友可以參考下
    2023-08-08

最新評(píng)論

读书| 友谊县| 泸水县| 天等县| 正宁县| 湘潭市| 淄博市| 洛扎县| 玛多县| 邓州市| 汤阴县| 当涂县| 江源县| 赤城县| 伊通| 景洪市| 沾益县| 剑河县| 聂拉木县| 定日县| 信丰县| 中西区| 资阳市| 饶河县| 湟源县| 怀远县| 红原县| 临漳县| 广州市| 屯门区| 上虞市| 宜兰市| 广德县| 炉霍县| 建水县| 故城县| 上栗县| 冀州市| 桐城市| 赣州市| 东莞市|