<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Apache HttpClient 4.5.x 學習總結二:Request execution

      請求執行(Request execution)

      1.什么是請求執行

        • Request execution 是指從發送HTTP請求到獲取響應整個過程的實現機制

      HttpClient 的核心功能是執行 HTTP 方法。HTTP 方法的執行涉及一次或多次 HTTP 請求/響應交換,通常由 HttpClient 內部處理。用戶需提供要執行的請求對象,HttpClient 負責將請求發送至目標服務器,返回對應的響應對象;若執行失敗,則拋出異常。

      1.1 通俗解釋

      可以把 Request execution 想象成一次快遞寄送過程:

      • 快遞公司(CloseableHttpClient):就像是一家快遞公司,提供了各種寄送服務,比如標準快遞、加急快遞等。
      • 包裹處理(請求準備):你把要寄送的物品(請求數據)打包好,寫上收件人地址(URL)和寄件人信息(頭部信息)。
      • 運輸過程(傳輸處理):快遞公司安排貨車或者飛機(連接)來運輸包裹。在運輸途中,可能會遇到堵車(超時)、需要繞行(重定向)等情況。
      • 送達簽收(響應解析):包裹送達后,收件人會簽收(返回響應),然后信息再反饋給你(解析響應數據)。
      • 車輛調度(連接管理):快遞公司不會每次送完一個包裹就把車扔掉,而是會根據情況決定是讓車繼續跑下一趟(Keep-Alive),還是入庫備用(連接池)。

      1.2 專業解釋

      1. 請求執行流程
      • 連接管理:會從連接池里獲取或者新建一個連接,并且要保證連接的有效性。
      • 請求準備:把 HTTP 請求轉換為可以傳輸的格式,同時添加必要的頭部信息,像 User-Agent、Content-Type 等。
      • 傳輸處理:借助底層的 Socket 進行數據傳輸,在這個過程中會處理諸如超時、重定向、認證等情況。
      • 響應解析:對服務器返回的數據進行解析,生成 HttpResponse 對象。
      • 連接釋放:根據 Keep-Alive 策略來決定是關閉連接還是將其返回到連接池。
      1. 核心組件
      • CloseableHttpClient:這是執行請求的主入口,負責管理連接和執行策略。
      • HttpRequestExecutor:負責處理請求的發送和響應的接收。
      • HttpClientContext:保存請求執行過程中的上下文信息,例如認證狀態、重定向歷史等。
      • ConnectionManager:對底層的連接資源進行管理。

      1.3 舉例和執行流程說明

      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;
      
      public class HttpClientExample {
          public static void main(String[] args) throws Exception {
              // 創建快遞公司(CloseableHttpClient)
              CloseableHttpClient httpClient = HttpClients.createDefault();
              
              try {
                  // 創建GET請求(包裹)
                  HttpGet httpGet = new HttpGet("https://www.example.com");
                  
                  // 執行請求(寄送包裹)
                  CloseableHttpResponse response = httpClient.execute(httpGet);
                  
                  try {
                      // 處理響應(簽收包裹)
                      System.out.println("Status Code: " + response.getStatusLine().getStatusCode());
                      System.out.println("Response Body: " + EntityUtils.toString(response.getEntity()));
                  } finally {
                      // 釋放資源
                      response.close();
                  }
              } finally {
                  // 關閉客戶端(關閉快遞公司)
                  httpClient.close();
              }
          }
      }
      

      執行流程說明:

        1. 創建客戶端:構建一個默認配置的 HttpClient 實例,就像開了一家快遞公司
        1. 創建請求:創建一個 HttpGet 對象,設置目標 URL,這類似于準備好要寄送的包裹并寫上地址。
        1. 執行請求:調用 httpClient.execute() 方法,這相當于把包裹交給快遞公司去寄送。
        1. 處理響應:獲取并解析服務器返回的狀態碼和內容,這就如同收到了包裹送達的反饋信息。
        1. 釋放資源:關閉響應和客戶端,類似于完成一次快遞業務后,清理相關資源。

      2 HTTP 請求 (HTTP request)

      所有 HTTP 請求都包含一個由方法名、請求 URI 和 HTTP 協議版本組成的請求行。

      HttpClient 原生支持 HTTP/1.1 規范定義的所有方法:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS。每種方法有對應的類:HttpGet, HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace, HttpOptions。

      請求 URI 是標識請求資源的統一資源標識符,包含協議方案、主機名、端口(可選)、資源路徑、查詢參數(可選)和片段(可選)。

      代碼示例

      // 直接構建 URI
      HttpGet httpget = new HttpGet("http://www.google.com/search?hl=en&q=httpclient");
      
      // 使用 URIBuilder 構建(推薦)
      URI uri = new URIBuilder()
          .setScheme("http")
          .setHost("www.google.com")
          .setPath("/search")
          .addParameter("q", "httpclient") // 自動編碼參數
          .build();
      HttpGet httpget = new HttpGet(uri);
      

      解讀

      • 請求組成:方法 + URI + 協議版本。
      • 方法支持:覆蓋 HTTP/1.1 全部方法,每方法有專屬類。
      • URI 構建:推薦使用 URIBuilder 自動處理編碼和結構。

      3 HTTP 響應 (HTTP response)

      HTTP 響應是服務器接收并解析請求后返回的消息。首行包含協議版本、數字狀態碼和狀態文本。

      代碼示例

      HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
      System.out.println(response.getStatusLine()); // 輸出: "HTTP/1.1 200 OK"
      

      解讀

      • 響應結構:協議版本 + 狀態碼 + 狀態文本(如 HTTP/1.1 200 OK)。
      • 關鍵信息:通過 StatusLine 對象獲取狀態詳情。

      4 消息頭處理 (Working with message headers)

      HTTP 消息可包含多個描述消息屬性的頭部(如 Content-Length, Content-Type)。HttpClient 提供檢索、添加、刪除和枚舉頭部的方法。

      代碼示例

      response.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
      
      // 獲取首個/最后一個指定頭部
      Header firstHeader = response.getFirstHeader("Set-Cookie"); 
      
      // 遍歷所有 Set-Cookie 頭部(高效方式)
      HeaderIterator it = response.headerIterator("Set-Cookie");
      while (it.hasNext()) {
          System.out.println(it.next());
      }
      
      // 解析頭部值(如拆解 Cookie 的鍵值對)
      HeaderElementIterator elemIt = new BasicHeaderElementIterator(response.headerIterator("Set-Cookie"));
      while (elemIt.hasNext()) {
          HeaderElement elem = elemIt.nextElement();
          System.out.println(elem.getName() + " = " + elem.getValue());
          for (NameValuePair param : elem.getParameters()) {
              System.out.println(" " + param);
          }
      }
      

      解讀

      • 頭部操作:支持增刪改查和迭代。
      • 高效遍歷HeaderIterator 避免創建臨時數組。
      • 復雜解析HeaderElementIterator 可拆解含多個鍵值對的頭部(如 Set-Cookie)。

      5 HTTP 實體 (HTTP entity)

      HTTP 消息可攜帶與請求/響應關聯的內容實體。實體在請求(如 POST/PUT)和響應中是可選的。HttpClient 將實體分為三類:

      1. 流式 (Streamed):內容來自流(如網絡響應),通常不可重復讀取。
      2. 自包含 (Self-contained):內容在內存中(如 StringEntity, ByteArrayEntity),可重復讀取。
      3. 包裝 (Wrapping):內容來自其他實體。

      關鍵點

      • 可重復性:僅自包含實體(如 ByteArrayEntity)支持多次讀取。
      • 字符編碼:字符類實體(如文本)需指定編碼(如 UTF-8)。

      代碼示例

      // 創建帶編碼的文本實體
      StringEntity entity = new StringEntity("重要消息", ContentType.create("text/plain", "UTF-8"));
      System.out.println(entity.getContentType()); // Content-Type: text/plain; charset=utf-8
      System.out.println(EntityUtils.toString(entity)); // "重要消息"
      

      6 確保釋放底層資源 (Ensuring release of resources)

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

      代碼示例

      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(); // 關閉響應
      }
      

      關鍵區別

      • 關閉內容流(instream.close())會嘗試消費實體內容以保持底層連接存活;
      • 關閉響應(response.close())會立即終止并丟棄連接。

      6.1. 資源釋放的核心邏輯

      • 雙重保險機制:通過 try-finally 嵌套確保:
        • 內容流(instream)優先在內部 finally 關閉
        • 響應(response)在外部 finally 兜底關閉
      • 本質目標:防止網絡連接、內存等資源泄漏,尤其在高并發場景下。

      6.2. 關閉內容流 vs 關閉響應的本質區別

      操作 連接狀態 適用場景
      instream.close() 保持活躍可復用 需復用連接的高性能場景
      response.close() 立即終止丟棄 無需復用或部分讀取的優化場景

      6.3. 關鍵實踐原則

      • 完全消費原則:若實體內容未完全讀?。ㄈ鐑H讀部分字節),必須關閉響應而非內容流,否則會導致連接僵滯。
      • 工具類輔助EntityUtils.consume(entity) 封裝了內容消費與流關閉邏輯,簡化代碼。
      • 寫入資源釋放writeTo() 方法內部若調用 getContent(),同樣需顯式關閉流。

      6.4. 性能取舍場景

      當僅需讀取響應頭或少量數據時(如檢查文件頭),強制消費整個實體(以復用連接)可能得不償失。此時直接關閉響應犧牲連接復用性,換取更高吞吐效率。

      6.5. 資源安全層次

      結論:關閉響應(response.close())會級聯釋放所有關聯資源,是最徹底的清理方式;而關閉流僅釋放內存/文件資源,不影響連接狀態。

      7 消費實體內容 (Consuming entity content)

      推薦使用 HttpEntity.getContent()writeTo(OutputStream) 消費內容。EntityUtils 提供便捷方法(如 toString(entity)),但除非響應實體來自可信HTTP服務器且長度有限,否則強烈不建議使用 EntityUtils。

      安全消費示例

      try (CloseableHttpResponse response = httpclient.execute(httpget)) {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
              long len = entity.getContentLength();
              if (len != -1 && len < 2048) {
                  System.out.println(EntityUtils.toString(entity)); // 小內容直接轉換
              } else {
                  try (InputStream instream = entity.getContent()) {
                      // 流式處理大內容
                  }
              }
          }
      }
      

      多次重復讀取實體

      若需重復讀取實體內容,必須通過內存或磁盤進行緩沖,最簡單的方式市使用 BufferedHttpEntity 包裝原始實體,其會將內容讀入內存緩沖區,同時保留原始實體中的所有屬性。

      HttpEntity entity = response.getEntity();
      if (entity != null && !entity.isRepeatable()) {
          entity = new BufferedHttpEntity(entity); // 緩沖到內存實現重復讀取
      }
      

      8 生成實體內容 (Producing entity content)

      HttpClient 作為常見數據容器,提供多種實體類封裝內容:

      • StringEntity:字符串
      • ByteArrayEntity:字節數組
      • InputStreamEntity:輸入流(不可重復)
      • FileEntity:文件

      代碼示例

      // 發送文件
      FileEntity entity = new FileEntity(new File("data.txt"), ContentType.TEXT_PLAIN);
      HttpPost httppost = new HttpPost("http://host/upload");
      httppost.setEntity(entity); //注入實體
      

      實體內容生成策略:

      數據類型 專用類 關鍵特性
      文本 StringEntity 內存高效
      二進制數據 ByteArrayEntity 可重復讀取
      文件 FileEntity 支持大文件流式傳輸
      動態流 InputStreamEntity 不可重復(單次讀?。?/td>

      8.1 HTML 表單

      使用 UrlEncodedFormEntity 模擬表單提交。

      代碼示例

      List<NameValuePair> params = new ArrayList<>();
      params.add(new BasicNameValuePair("username", "admin"));
      params.add(new BasicNameValuePair("password", "123456"));
      UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
      HttpPost httppost = new HttpPost("http://host/login");
      httppost.setEntity(entity); // 內容: username=admin&password=123456
      

      此實體將生成URL編碼內容:username=admin&password=123456

      • 編碼機制:UrlEncodedFormEntity 自動將參數轉換為 x-www-form-urlencoded 格式
      • 關鍵陷阱:
      • 未顯式指定字符集(如 Consts.UTF_8)可能導致中文亂碼
      • 參數值需手動進行 URL 安全編碼(URLEncoder.encode())

      8.2 分塊傳輸 (Content chunking)

      啟用分塊編碼:

      StringEntity entity = new StringEntity("大數據", ContentType.TEXT_PLAIN);
      entity.setChunked(true); // 啟用分塊傳輸提示
      

      注意:僅當服務器支持(如 HTTP/1.1)時生效。

      • 優勢:無需預知總長度,支持動態生成內容
      • 限制: HTTP/1.0 不支持,此時忽略該標識

      9 響應處理器 (Response handlers)

      最簡潔的響應處理方式是使用 ResponseHandler 接口的 handleResponse(HttpResponse response) 方法。該方法自動管理連接釋放,無論請求成功或異常。

      代碼示例

      CloseableHttpClient httpclient = HttpClients.createDefault();
      HttpGet httpget = new HttpGet("http://localhost/json");
      
      // 定義響應處理器
      ResponseHandler<MyJsonObject> rh = response -> {
          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");
          }
          
          // 按字符集解析JSON
          ContentType contentType = ContentType.getOrDefault(entity);
          Charset charset = contentType.getCharset();
          Reader reader = new InputStreamReader(entity.getContent(), charset);
          return new Gson().fromJson(reader, MyJsonObject.class); // 自動關閉流
      };
      
      // 執行請求并自動處理連接釋放
      MyJsonObject myjson = httpclient.execute(httpget, rh); 
      

      優勢

      1. handleResponse 內完成狀態校驗→內容解析→資源轉換全流程
      2. 異常時自動拋出 HttpResponseException 保證連接釋放

      核心總結

      1. 執行流程

        graph LR A[創建請求對象] --> B[HttpClient.execute] B --> C{成功?} C -->|是| D[處理響應實體] C -->|否| E[處理異常] D --> F[確保關閉資源]
      2. 關鍵實踐

        • 資源釋放:始終用 try-with-resourcesfinally 塊關閉響應/流。
        • 實體選擇
          • 可重復讀取 → 用 ByteArrayEntity/StringEntity。
          • 大文件 → 用 FileEntity
        • 表單提交:用 UrlEncodedFormEntity 自動編碼參數。
        • 響應處理:優先用 ResponseHandler 簡化資源管理。
      3. 性能注意

        • 避免用 EntityUtils.toString() 處理大響應。
        • 流式實體 (InputStreamEntity) 不可重復,需謹慎使用。
      posted @ 2025-07-18 18:04  hqq的進階日記  閱讀(39)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日产中文字幕在线精品一区| 国产精品毛片av999999| xxxx丰满少妇高潮| 日韩一区二区三区水蜜桃| 国产99视频精品免费视频36| 免费无码黄动漫在线观看| 国产亚洲精品久久久久婷婷图片 | 中文字幕日韩有码一区| 亚洲精品www久久久久久| 亚洲AV片一区二区三区| 亚洲日韩久热中文字幕| 九九久久人妻一区精品色| 在线精品自拍亚洲第一区| 久久精品国产亚洲成人av| 精品无码成人片一区二区| 兴文县| 精品视频福利| 欧美成本人视频免费播放| 国产一区二区日韩在线| 国产精品小仙女自拍视频| 久久精品中文字幕少妇| 天堂网亚洲综合在线| 国产精品高清视亚洲精品| ww污污污网站在线看com| 精品国产乱码久久久久夜深人妻 | 黑人好猛厉害爽受不了好大撑| 亚洲AV无码AV在线影院| 海兴县| 精品尤物TV福利院在线网站 | 欧美饥渴熟妇高潮喷水| 熟女人妻视频| 激情综合网激情五月我去也| 亚洲欧美日韩综合在线丁香| 狠狠亚洲色一日本高清色| 精品国产中文字幕在线看| 国产精品国产三级国快看| 国产鲁鲁视频在线观看| 18禁无遮拦无码国产在线播放| 欧美成人h亚洲综合在线观看| 亚洲深深色噜噜狠狠网站| 亚洲日韩乱码中文无码蜜桃臀|