91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

HttpClient基礎解析

發布時間:2020-10-10 14:51:08 來源:腳本之家 閱讀:155 作者:回眸一笑百媚生 欄目:編程語言

本文講述了HttpClient基礎知識,對相關概念進行解釋在這里分享給大家,供大家參考。

1. 請求執行:

HttpClient最重要的功能是執行HTTP方法。執行HTTP方法涉及一個或多個HTTP請求/ HTTP響應交換,通常由HttpClient內部處理。用戶期望提供一個請求對象來執行,并且希望HttpClient將請求發送到目標服務器返回相應的響應對象,如果執行失敗則拋出異常。

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

這是一個請求執行過程的一個例子,它的最簡單的形式是:

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

1.1. HTTP請求

所有HTTP請求都有一個請求行,包括方法名稱,請求URI和HTTP協議版本。

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

Request-URI是統一資源標識符,用于標識應用請求的資源。HTTP請求URI由協議方案,主機名,可選端口,資源路徑,可選查詢和可選片段組成。

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響應

HTTP響應是在接收和解釋請求消息之后由服務器發送回客戶端的消息。該消息的第一行包括協議版本,后跟數字狀態代碼及其關聯的文本短語。

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());
//輸出結果
/*
HTTP/1.1
200
OK
HTTP/1.1 200 OK
*/

1.3. 處理消息頭

HTTP消息可以包含描述消息屬性的多個頭部,如內容長度,內容類型等。HttpClient提供了檢索,添加,刪除和枚舉頭文件的方法。
獲取給定類型的所有標頭的最有效的方法是使用 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()); 
}

它還提供了方便的方法來將HTTP消息解析為單獨的頭元素。

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實體

HTTP消息可以攜帶與請求或響應相關聯的內容實體。實體可以在一些請求和一些響應中找到,因為它們是可選的。使用實體的請求被稱為實體封裝請求。HTTP規范定義了兩個實體封裝請求方法:POST和 PUT。響應通常期望包含內容實體。有例外的情況,如應對 HEAD方法204 No Content, 304 Not Modified,205 Reset Content 響應。

HttpClient根據其內容來源區分三種實體:

streamed: 內容是從流中接收的,或者即時生成的。特別地,該類別包括從HTTP響應接收到的實體。流式實體通常不可重復。

self-contained: 內容在內存中或通過獨立于連接或其他實體的方式獲取。自包含的實體通常是可重復的。這種類型的實體將主要用于封閉HTTP請求的實體。

wrapping: 內容是從另一個實體獲得的。

當從HTTP響應流出內容時,此區別對于連接管理很重要。對于由應用程序創建并且僅使用HttpClient發送的請求實體,流和獨立的區別不重要。在這種情況下,建議將不可重復的實體視為流式傳輸,將可重復的實體視為獨立的。

1.4.1. 可重復的實體

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

1.4.2. 使用HTTP實體

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

當執行帶有封閉內容的請求時,或者當請求成功并且使用響應主體將結果發送回客戶端時,實體被創建。

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

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

當為外發消息創建實體時,該元數據必須由實體的創建者提供。

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. 確保發布低級別資源

為了確保系統資源的正確釋放,必須關閉與實體或響應本身相關聯的內容流

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(); 
}

關閉內容流和關閉響應之間的區別在于,前者將嘗試通過占用實體內容來保持底層連接,而后者會立即關閉并放棄連接。
請注意,HttpEntity.writeTo(OutputStream) 一旦實體完全寫出,還需要確保正確釋放系統資源的方法。如果此方法獲取一個java.io.InputStream通過調用 的實例 HttpEntity.getContent(),那么也希望在finally子句中關閉流。

當使用流實體時,可以使用該 EntityUtils.consume(HttpEntity)方法來確保實體內容已被完全消耗,底層流已經被關閉。

然而,可能會有情況,當只需要檢索整個響應內容的一小部分時,消耗剩余內容并使連接可重用的性能損失太高,在這種情況下,可以通過關閉終止內容流響應。

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(); 
}

連接不會重復使用,但由其持有的所有級別資源將被正確地分配。

1.6. 消費實體內容

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

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(); 
}

在某些情況下,可能需要多次讀取實體內容。在這種情況下,實體內容必須以某種方式緩存,無論是在內存還是在磁盤上。最簡單的方法是通過用BufferedHttpEntity類包裝原始實體。這將導致將原始實體的內容讀入內存緩沖區。在所有其他方面,實體包裝器將具有原始包裝器。

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

1.7. 制作實體內容

HttpClient提供了幾個類,可以通過HTTP連接高效地流出內容。這些類的實例可以與實體包圍請求,如相關聯POST并PUT 以包圍實體內容分成傳出HTTP請求。HttpClient的提供了幾個類為最常見的數據的容器,如字符串,字節數組,輸入流,和文件: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表單
許多應用程序需要模擬提交HTML表單的過程,例如,以登錄到Web應用程序或提交輸入數據。HttpClient提供實體類 UrlEncodedFormEntity來促進進程。

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實例將使用所謂的URL編碼來對參數進行編碼并產生以下內容:

param1=value1&param2=value2

1.7.2. 內容分塊

一般建議讓HttpClient根據正在傳輸的HTTP消息的屬性選擇最合適的傳輸編碼。然而,可以通知HttpClient,通過設置HttpEntity.setChunked()為true,優先選擇塊編碼。請注意,HttpClient只會使用此標志作為提示。當使用不支持塊編碼的HTTP協議版本(如HTTP / 1.0)時,此值將被忽略。

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. 響應處理程序

處理響應的最簡單和最方便的方法是使用ResponseHandler包含該handleResponse(HttpResponse response)方法的界面。這種方法完全可以緩解用戶不必擔心連接管理。使用ResponseHandlerHttpClient 時 ,無論請求執行是成功還是導致異常,HttpClient都會自動保證將連接釋放回連接管理器。

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);

總結

以上是本文對HttpClient基礎知識的全部介紹,希望對大家有所幫助。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

赤水市| 海伦市| 永泰县| 宁陵县| 湘乡市| 盈江县| 新宁县| 邢台市| 吐鲁番市| 奇台县| 鄢陵县| 兴国县| 巴青县| 庆元县| 长春市| 和平县| 南涧| 永年县| 淮阳县| 重庆市| 银川市| 无锡市| 庄河市| 彭泽县| 通许县| 隆安县| 诏安县| 凌云县| 黔江区| 五河县| 蚌埠市| 兴城市| 扎鲁特旗| 石景山区| 遵化市| 兴安县| 图们市| 留坝县| 社旗县| 定兴县| 淅川县|