我想使用apache async http客户端进行异步http调用,以便为每个线程运行多个调用。
此处列出了代码:https://hc.apache.org/httpcomponents-asyncclient-dev/quickstart.html
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
// Start the client
httpclient.start();
// One most likely would want to use a callback for operation result
final CountDownLatch latch1 = new CountDownLatch(1);
final HttpGet request2 = new HttpGet("http://www.apache.org/");
httpclient.execute(request2, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response2) {
latch1.countDown();
System.out.println(request2.getRequestLine() + "->" + response2.getStatusLine());
}
public void failed(final Exception ex) {
latch1.countDown();
System.out.println(request2.getRequestLine() + "->" + ex);
}
public void cancelled() {
latch1.countDown();
System.out.println(request2.getRequestLine() + " cancelled");
}
});
latch1.await();
我最后一次在nodejs中编程,并对promise方法非常满意。我找到的最近的项目是来自GUAVA的ListenableFuture。 (我不能使用Java 8)。问题是如何将回调方法转换为ListenableFuture。
在nodejs中这很容易,因为在回调中我可以调用resolve函数。我不知道如何在Java中这样做,我没有在谷歌中找到如何做到这一点。
答案 0 :(得分:1)
如API所述,execute
方法返回Future。由于它与回调链接,因此它应该是一个ListenableFuture
ListenableFuture<HttpResponse> future = (ListenableFuture<HttpResponse>) httpclient.execute(...);
应该做的伎俩(在回调中,你不能这样做)。从技术上讲,你甚至不需要投射Future,因为正常的Future应该足以满足你的用例,因为你不需要更多的回调,如果我有你的话。
如果你想彻底摆脱回调(什么是不那么混乱的解决方案)你需要使用HttpClient的另一个实现,但它需要重写代码。
在回调中,你无法获得未来,反正你也不需要它,因为未来的结果是回调的参数。
答案 1 :(得分:0)
以下帖子非常有用:Turning a listener into a future in java 我想做的是:
// One most likely would want to use a callback for operation result
final SettableFuture<String> future = SettableFuture.create();
final HttpGet request2 = new HttpGet("http://www.apache.org/");
httpclient.execute(request2, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response2) {
future.set(request2.getRequestLine() + "->" + response2.getStatusLine());
}
public void failed(final Exception ex) {
future.set(request2.getRequestLine() + "->" + ex);
}
public void cancelled() {
future.set(request2.getRequestLine() + " cancelled");
}
});