簡體   English   中英

Java 的異步 HTTP 客戶端

[英]Asynchronous HTTP Client for Java

作為 Java 世界中的一個相對新手,我發現許多其他框架中相對微不足道的事情令人沮喪地難以完成。 一個主要示例是異步 http 請求的簡單解決方案。 看到一個似乎並不存在,最好的方法是什么? 使用像 httpclient 這樣的阻塞類型庫或內置的 java http 東西創建我自己的線程,或者我應該使用更新的非阻塞 io java 東西 - 對於應該簡單的東西來說似乎特別復雜。

我正在尋找的是從開發人員的角度來看易於使用的東西 - 類似於 AS3 中的 URLLoader - 您只需創建一個 URLRequest - 附加一堆事件處理程序來處理完成、錯誤、進度等,然后調用一種將其關閉的方法。

如果您不熟悉 AS3 中的 URLLoader,它非常簡單,看起來像這樣:

private void getURL(String url)
{
    URLLoader loader = new URLLoader();
    loader.addEventListener(Event.Complete, completeHandler);
    loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
    loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

    URLRequest request = new URLRequest(url);

    // fire it off - this is asynchronous so we handle
    // completion with event handlers
    loader.load(request);
}

private void completeHandler(Event event)
{
    URLLoader loader = (URLLoader)event.target;
    Object results = loader.data;

    // process results
}

private void httpStatusHandler(Event event)
{
    // check status code
}

private void ioErrorHandler(Event event)
{
    // handle errors
}

Java 中的異步 HTTP 客戶端有多種選擇

  1. Java 8:使用以前稱為 ning http 客戶端庫的async-http-client
  2. Java 11 及更高版本:JDK 現在帶有java.net.http。 完全異步的HttpClient
  3. Square 的OkHttpClient 支持同步阻塞和帶回調的異步調用。 在安卓上很受歡迎。

Apache Commons HttpClient 4.0 版(現在在HttpComponents/HttpCore 中)也支持 Java 的 NIO(非阻塞 IO)。 我認為這是你最好的選擇。

如果您還沒有看過它,請查看 Java 5 java.util.concurrent——它使多線程應用程序更易於開發。 您可以設置一個管理四個線程的 ThreadPoolExecutor。 然后,您可以向池提供任意數量的任務以完成。 每個任務都是一個 Runnable。 ThreadPoolExecutor 將對 Runnable 任務進行排隊,並將它們並行提供給可用的線程。 每個 Runnable 任務完成時都會調用 Pool 的 afterExecute() 方法。

我清楚地記得在 1999 年為一個用 Java 編寫的 Web 瀏覽器編寫了一個fetch線程池,而且它是正確的。 上個月,我為 Web 服務器編寫了一個負載測試器。 測試器有一個 ThreadPoolExecutor,它有 n 個線程,我提供給它的 Runnable 任務每個都使用 Apache HTTP 客戶端獲取一個頁面。 只花了一兩個小時就讓它工作得相當好。 我認為您會喜歡 java.util.concurrent 與 Apache HTTP 客戶端相結合,盡管聽起來您需要對進度指示進行一些自定義。

(請注意,Apache HTTP 客戶端有自己的線程池,默認配置將您限制為最多 20 個線程,每個 Web 服務器只有兩個線程。)

更新:這是Apache HTTP Client的鏈接。 請務必閱讀MultiThreadedHttpConnectionManager ,它負責處理連接池,並且在最基本的示例中沒有顯示。

Jetty HTTP 客戶端是異步的。

看起來你想要 NIO 的(一部分)——這里有一個很好的教程,異步網絡部分從 p 開始。 30,最后有很多有用的鏈接。

在 NIO/Netty 之上編寫了一些庫和框架 - RxNettyVertx有助於編寫異步 HTTP 客戶端

下面是使用 vertx 的示例代碼

public class Client extends AbstractVerticle {

  @Override
  public void start() throws Exception {
    //lambda callback would be called when the response comes back
    vertx.createHttpClient().getNow(8080, "localhost", "/", resp -> {
      System.out.println("Got response " + resp.statusCode());
      resp.bodyHandler(body -> {
        System.out.println("Got data " + body.toString("ISO-8859-1"));
      });
    });
   //this code statement will execute before response comes back
   System.out.println("I am not blocked");
  }
}

你可以從這里找到完整的示例代碼

因此,可能值得考慮的是 actionscript 和 Java 不服務於相同的利基市場。 例如,Java 確實讓一些事情變得更加乏味 - 但通常是為用戶提供更多選項,例如如何執行 HTTP 連接,而 actionscript 可能會抽象出細節或可能的錯誤以方便使用。 但是,你的觀點仍然成立。

我自己不知道 Java 的異步 HTTP 客戶端。 Alex Martelli 的回答談到了 Java 的 NIO,如果您有興趣在自己的代碼中實現 HTTP 協議,這是一個很好的回答。 NIO 將允許您使用套接字連接到 Web 服務器 - 但是您必須手動創建自己的 GET 請求並解析傳入的 HTTP 標頭/數據。

另一種選擇是使用 java.net.URL 類 - 您可以在網上和 stackoverflow 上找到許多教程。 您可以將它們包裝在線程中 - 因此您的 java 程序有多個執行線程。

但是隨后您遇到了同步問題。 我同意,這是一種痛苦,但它提供了更細粒度的靈活性。

(我意識到這並不能回答你的問題——如果有人真的知道一個 java 工具來執行異步 http 請求,我很想知道!)

AFAIK TCPMon 工具采用與您描述的方法類似的方法。 您可以在他們的SVN 瀏覽器中查看源代碼

還可以查看WGET-java以了解阻塞代碼的內容。

但是你必須用Java寫這個嗎? 還有很多其他方法使用 JRuby 或 Rhino 來輕松完成類似的事情,這些方法將在 JVM 上運行,但不是用 Java 編寫的。

httpunithtmlunit是 2 個可定制和可配置的 Java http 客戶端,能夠用於任何瀏覽器,例如模擬 firefox、無頭瀏覽、預定軟件客戶端和代理。

還可以查看http://www.javaworld.com/javaworld/jw-03-2008/jw-03-asynchhttp.html本文討論基於名為 xLightweb 的 HttpClient 的異步 HTTP

我建議為此觸發單獨的線程。

我剛剛偶然發現了在 Geronimo 中實現的異步 HTTP 客戶端。 您可能還想看看它,在http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/ - 警告:最新的提交似乎超過一年了。

另一個構建異步 HTTP 客戶端的項目是 xsocket:xsocket.sourceforge.net

Asyncweb 提供了一個異步 http 客戶端及其 http 服務器。 可從以下位置下載:

https://svn.apache.org/repos/asf/mina/asyncweb/trunk

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM