CodeGym/Java Course/Module 3 a ɛto so abien/使用 HttpClient 發出請求

使用 HttpClient 發出請求

開放

4.1 send()方法,BodyHandlers

您已經完成瞭如何形成http 請求的學習,因此您可以繼續進行最重要的事情 - 發送此請求。在最簡單的情況下,這很容易做到:

HttpRequest request = HttpRequest.newBuilder(new URI("https://codegym.cc")).build();

   HttpClient client = HttpClient.newBuilder()
        .version(Version.HTTP_1_1)
        .build();

   HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
   System.out.println(response.statusCode() );
   System.out.println(response.body() );

這些是什麼BodyHandlers?你怎麼認為?您發送了一個請求,這意味著您應該收到一個答复 - http response。這個響應可以有response body:一個字符串、一個文件、一個字節數組、一個 InputStream。

是的,是的,沒錯。就像在形成請求時,您需要指定response body響應的類型。一共可以有8塊:

  • BodyHandlers.ofByteArray
  • BodyHandlers.ofString
  • BodyHandlers.ofFile
  • BodyHandlers.discarding
  • BodyHandlers.replacing
  • BodyHandlers.ofLines
  • BodyHandlers.fromLineSubscriber

根據BodyHandlers您傳遞給方法的類型send(),它會返回這樣的結果類型。例子:

// response body is ignored
HttpResponse<Void> response = client.send(request, BodyHandlers.discarding());
// response body is a string
 HttpResponse<String>response = client.send(request, BodyHandlers.ofString());
// response body is a file
HttpResponse<Path> response = client.send(request, BodyHandlers.ofFile(Paths.get("readme.txt")));
// response body is an InputStream
HttpResponse<InputStream> response = client.send(request, BodyHandlers.ofInputStream());

如果應將文件作為響應發送給您,則BodyHandlers.ofFile()需要將本地文件的名稱傳遞給該方法,該文件將由 HttpClient 對象保存在該方法中。

4.2 followRedirects()方法

301此外,在發送請求時,您可以指定如果服務器發送或302(臨時或永久重定向)響應HttpClient 應該做什麼。假設服務器發送了一個代碼302,您需要:跟踪這種情況,從響應中獲取新的 URL,並將請求發送到新地址。

我不太願意這樣做,特別是考慮到這種情況很常見並且在所有 http 客戶端中早已實現自動化。同樣在此 HttpClient 中,您只需要指定發送請求時選擇的重定向模式。

HttpResponse response = HttpClient.newBuilder()
  .followRedirects( HttpClient.Redirect.ALWAYS )
  .build()
  .send(request, BodyHandlers.ofString());

重定向只有 3 個選項:

  • ALWAYS——一直;
  • NEVER——從不;
  • 正常- 總是,除了 HTTPS -> HTTP。

如您所見,這裡的選項不多,但有定制能力總比沒有好。

4.4 proxy() 方法

還有一些更有用但不常用的選項。在你需要它們之前你不需要它們:)

第一個是代理。在日常生活中,你不會經常遇到它們,但很多大公司內部都有復雜的互聯網流量安全系統,因此代理設置也各不相同。

好吧,當然,您的軟件將在這樣一家公司的內部某個地方運行,總有一天會遇到需要使用代理的事實。因此,這裡也有這樣的選擇是件好事。

設置代理非常簡單 - 例如:

HttpResponse<String> response = HttpClient.newBuilder()
  .proxy( ProxySelector.getDefault())
  .build()
  .send(request, BodyHandlers.ofString());

此處已選擇默認代理,但您可能需要設置自己的代理:

HttpResponse response = HttpClient.newBuilder()
  .proxy(ProxySelector.of(new InetSocketAddress("proxy.microsoft.com", 80)))
  .build()
  .send(request, BodyHandlers.ofString());

我們不會考慮如何使用代理,因為這不包括在本課程的範圍內。

4.5 驗證器()

還有一點很重要。HTTP 協議支持身份驗證。就在協議級別。

現在這種方法幾乎不用了,但大約 20 年前它很常見。Http 請求如下所示:

http://username@example.com/

或者甚至像這樣:

http://username:password@example.com/

這不是郵件。這正是鏈接。是的,你不這麼認為。可以在 http 請求中直接指定登錄名甚至密碼。是的,即使現在你也可以。這就是為什麼我寫道,現在通常沒有人這樣做。但是有這樣的可能。

Authenticator auth = new Authenticator() {
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(
     "username",
        "password".toCharArray());
    }
};

HttpResponse<String> response = HttpClient.newBuilder()
  .authenticator(auth).build()
  .send(request, BodyHandlers.ofString());

這很有趣!你知道為什麼而不是“password"在它說的代碼中"password".toCharArray()嗎?

因為構造函數的第二個參數PasswordAuthentication 不是String,而是CharArray

為什麼第二個參數不是String,嗯CharArray

因為為了安全起見,所有的密碼都不允許作為一個完整的字符串存儲,即使是在你自己的應用程序中也是如此。也就是說,您的應用程序在其內存中不應將密碼存儲為字符串。這樣一來,如果有人弄濕了記憶,就無法從中提取密碼...

但與此同時,密碼可以通過不安全的 HTTP 協議傳輸到半個世界 :) :) :)

出色地。世界並不完美。

您可以在以下鏈接中閱讀有關此主題的更多信息:

HTTP認證

了解 HTTP 身份驗證

留言
  • 受歡迎
你必須登入才能留言
此頁面尚無留言