[英]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.