1

我有以下方法,它使用 Apache Commons Http 客户端向给定的 URI 发送异步 GET 并返回 Future 和响应。

CloseableHttpAsyncClient 实现 Closeable 因此我使用 try/resource 结构。

public static Future<HttpResponse> sendAsyncGet(String uri) throws IOException {
    try (CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.createDefault()) {
        asyncHttpClient.start();
        HttpGet httpGet = new HttpGet(uri);
        return asyncHttpClient.execute(httpGet, null);
    }

下面你可能会看到用法:

Future<HttpResponse> future = sendAsyncGet("http://www.apache.org");
future.get(3, TimeUnit.SECONDS);

问题是,当我在未来调用 get 时,它不会返回所需的 HttpResponse。如果我使用重载的 get() 方法,它会一直等到超时或永远。我想这是因为 try/resource 没有正确释放。

如何改进给定的方法/代码以便能够正确使用:Future with try/resource structure包含在方法主体中?

更新:

这是maven依赖:

   <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpasyncclient</artifactId>
        <version>4.1.1</version>
        <scope>test</scope>
    </dependency>
4

1 回答 1

1

Try with resources 将在收到响应之前关闭异步客户端。

您可能希望从您传递给执行调用的未来回调中关闭异步客户端。

public static Future<HttpResponse> sendAsyncGet(String uri) throws IOException {
    final CloseableHttpAsyncClient asyncHttpClient;

    asyncHttpClient = HttpAsyncClients.createDefault();
    asyncHttpClient.start();

    return asyncHttpClient.execute(new HttpGet(uri), new FutureCallback<HttpResponse>() {
        private void close() {
            try {
                asyncHttpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void completed(HttpResponse response) {
            close();
            System.out.println("completed");
        }

        @Override
        public void failed(Exception e) {
            close();
            e.printStackTrace();
        }

        @Override
        public void cancelled() {
            close();
            System.out.println("cancelled");
        }
    });
}
于 2016-03-12T20:08:30.370 回答