I usually post about HTTP stuff on Twitter - you can follow me there:

1. Overview

In this tutorial we’ll illustrate the most common use cases of the Apache HttpAsyncClient – from basic usage, to how to set up a proxy, how to use SSL certificate and finally – how to authenticate with the async client.

2. Simple Example

First – let’s see how to use HttpAsyncClient in a simple example – send a GET request:

@Test
public void whenUseHttpAsyncClient_thenCorrect() throws Exception {
    CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
    client.start();
    HttpGet request = new HttpGet("http://www.google.com");
    
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we need to start the async client before using it; without that, we would get the following exception:

java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: INACTIVE
    at o.a.h.u.Asserts.check(Asserts.java:46)
    at o.a.h.i.n.c.CloseableHttpAsyncClientBase.
      ensureRunning(CloseableHttpAsyncClientBase.java:90)

3. Multi-Threading with HttpAsyncClient

Now – let’s see how to use HttpAsyncClient to execute multiple requests simultaneously.

In the following example – we send three GET requests to three different host using HttpAsyncClient and PoolingNHttpClientConnectionManager:

@Test
public void whenUseMultipleHttpAsyncClient_thenCorrect() throws Exception {
    ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
    PoolingNHttpClientConnectionManager cm = 
      new PoolingNHttpClientConnectionManager(ioReactor);
    CloseableHttpAsyncClient client = 
      HttpAsyncClients.custom().setConnectionManager(cm).build();
    client.start();
    
    String[] toGet = { 
        "http://www.google.com/", 
        "http://www.apache.org/", 
        "http://www.bing.com/" 
    };

    GetThread[] threads = new GetThread[toGet.length];
    for (int i = 0; i < threads.length; i++) {
        HttpGet request = new HttpGet(toGet[i]);
        threads[i] = new GetThread(client, request);
    }

    for (GetThread thread : threads) {
        thread.start();
    }
    for (GetThread thread : threads) {
        thread.join();
    }
}

Here is our GetThread implementation to handle the response:

static class GetThread extends Thread {
    private CloseableHttpAsyncClient client;
    private HttpContext context;
    private HttpGet request;

    public GetThread(CloseableHttpAsyncClient client,HttpGet req){
        this.client = client;
        context = HttpClientContext.create();
        this.request = req;
    }

    @Override
    public void run() {
        try {
            Future<HttpResponse> future = client.execute(request, context, null);
            HttpResponse response = future.get();
            assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
        } catch (Exception ex) {
            System.out.println(ex.getLocalizedMessage());
        }
    }
}

4. Proxy with HttpAsyncClient

Next – let’s see how to set up and use a proxy with the HttpAsyncClient.

In the following example – we send a HTTP GET request over proxy:

@Test
public void whenUseProxyWithHttpClient_thenCorrect() throws Exception {
    CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
    client.start();
    
    HttpHost proxy = new HttpHost("74.50.126.248", 3127);
    RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
    HttpGet request = new HttpGet("https://issues.apache.org/");
    request.setConfig(config);
    
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

5. SSL Certificate with HttpAsyncClient

Now – let’s see how to use a SSL Certificate with HttpAsyncClient.

In the following example – we configure HttpAsyncClient to accept all certificates:

@Test
public void whenUseSSLWithHttpAsyncClient_thenCorrect() throws Exception {
    TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
        public boolean isTrusted(X509Certificate[] certificate,  String authType) {
            return true;
        }
    };
    SSLContext sslContext = SSLContexts.custom()
      .loadTrustMaterial(null, acceptingTrustStrategy).build();

    CloseableHttpAsyncClient client = HttpAsyncClients.custom()
      .setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
      .setSSLContext(sslContext).build();
    client.start();
    
    HttpGet request = new HttpGet("https://mms.nw.ru/");
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

6. Cookies with HttpAsyncClient

Next – let’s see how to use cookies with HttpAsyncClient.

In the following example – we set a cookie value before sending the request:

@Test
public void whenUseCookiesWithHttpAsyncClient_thenCorrect() throws Exception {
    BasicCookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
    cookie.setDomain(".github.com");
    cookie.setPath("/");
    cookieStore.addCookie(cookie);
    
    CloseableHttpAsyncClient client = HttpAsyncClients.custom().build();
    client.start();
    
    HttpGet request = new HttpGet("http://www.github.com");
    HttpContext localContext = new BasicHttpContext();
    localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
    Future<HttpResponse> future = client.execute(request, localContext, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

7. Authentication with HttpAsyncClient

Next – let’s see how to use authentication with HttpAsyncClient.

In the following example – we use the CredentialsProvider to access a host through basic authentication:

@Test
public void whenUseAuthenticationWithHttpAsyncClient_thenCorrect() throws Exception {
    CredentialsProvider provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pass");
    provider.setCredentials(AuthScope.ANY, creds);
    
    CloseableHttpAsyncClient client = 
      HttpAsyncClients.custom().setDefaultCredentialsProvider(provider).build();
    client.start();
    
    HttpGet request = new HttpGet("http://localhost:8080");
    Future<HttpResponse> future = client.execute(request, null);
    HttpResponse response = future.get();
    
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

8. Conclusion

In this article, we illustrated the various use cases of the asynchronous Apache Http client.

The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about HTTP stuff on Twitter - you can follow me there:


  • Tim Thomas

    I am trying to do and Async Post and even though I think I am providing the correct credentials (same as I use for a regular Post on the same server), I keep getting a 401 unauthorized response. Here’s a code snippet:

    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials( new AuthScope( ip, 80 ), new UsernamePasswordCredentials( id, pwd ) );

    CloseableHttpAsyncClient asyncClient = HttpAsyncClients.custom().setDefaultCredentialsProvider( credsProvider ).build();

    ContentType cntntType = ContentType.create( “text/xml” );
    HttpAsyncRequestProducer asyncRequest = HttpAsyncMethods.createPost( postCommand, sendData, cntntType );
    HttpAsyncResponseConsumer responseConsumer = new BasicAsyncResponseConsumer();
    Future future = null;
    asyncClient.start();
    future = asyncClient.execute( asyncRequest, responseConsumer,
    new FutureCallback() {
    public void completed(final HttpResponse response){}
    public void failed(final Exception ex) {}
    public void cancelled(){}
    }
    );
    logfp.write( “”+future.get() );
    logfp.newLine();
    logfp.flush();
    asyncRequest.close();
    asyncClient.close();

    Any thoughts on what I am missing or doing wrong?

    Thanks in advance for any help you can give me.

    tt