[英]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 客戶端有多種選擇
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 之上編寫了一些庫和框架 - RxNetty和Vertx有助於編寫異步 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 請求,我很想知道!)
還可以查看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 服務器。 可從以下位置下載:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.