从尝试资源结构中回归未来

时间:2016-03-12 18:02:32

标签: java return try-catch future autocloseable

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

CloseableHttpAsyncClient实现了Closeable,因此我使用了try / resource constructure。

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 on a future时,它不会返回所需的HttpResponse。如果我使用重载的get()方法,它会等到超时或永远超时。我想这是因为没有正确发布try / resource。

如何改进给定的方法/代码才能正确使用:方法体中包含try / resource结构的未来?

更新

这是maven依赖:

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

1 个答案:

答案 0 :(得分:1)

尝试使用资源将在收到响应之前关闭异步客户端。

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

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");
        }
    });
}