How do you create an asynchronous HTTP request in JAVA? How do you create an asynchronous HTTP request in JAVA? java java

How do you create an asynchronous HTTP request in JAVA?


If you are in a JEE7 environment, you must have a decent implementation of JAXRS hanging around, which would allow you to easily make asynchronous HTTP request using its client API.

This would looks like this:

public class Main {    public static Future<Response> getAsyncHttp(final String url) {        return ClientBuilder.newClient().target(url).request().async().get();    }    public static void main(String ...args) throws InterruptedException, ExecutionException {        Future<Response> response = getAsyncHttp("http://www.nofrag.com");        while (!response.isDone()) {            System.out.println("Still waiting...");            Thread.sleep(10);        }        System.out.println(response.get().readEntity(String.class));    }}

Of course, this is just using futures. If you are OK with using some more libraries, you could take a look at RxJava, the code would then look like:

public static void main(String... args) {    final String url = "http://www.nofrag.com";    rx.Observable.from(ClientBuilder.newClient().target(url).request().async().get(String.class), Schedulers            .newThread())            .subscribe(                    next -> System.out.println(next),                    error -> System.err.println(error),                    () -> System.out.println("Stream ended.")            );    System.out.println("Async proof");}

And last but not least, if you want to reuse your async call, you might want to take a look at Hystrix, which - in addition to a bazillion super cool other stuff - would allow you to write something like this:

For example:

public class AsyncGetCommand extends HystrixCommand<String> {    private final String url;    public AsyncGetCommand(final String url) {        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("HTTP"))                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()                        .withExecutionIsolationThreadTimeoutInMilliseconds(5000)));        this.url = url;    }    @Override    protected String run() throws Exception {        return ClientBuilder.newClient().target(url).request().get(String.class);    } }

Calling this command would look like:

public static void main(String ...args) {    new AsyncGetCommand("http://www.nofrag.com").observe().subscribe(            next -> System.out.println(next),            error -> System.err.println(error),            () -> System.out.println("Stream ended.")    );    System.out.println("Async proof");}

PS: I know the thread is old, but it felt wrong that no ones mentions the Rx/Hystrix way in the up-voted answers.


Note that java11 now offers a new HTTP api HttpClient, which supports fully asynchronous operation, using java's CompletableFuture.

It also supports a synchronous version, with calls like send, which is synchronous, and sendAsync, which is asynchronous.

Example of an async request (taken from the apidoc):

   HttpRequest request = HttpRequest.newBuilder()        .uri(URI.create("https://example.com/"))        .timeout(Duration.ofMinutes(2))        .header("Content-Type", "application/json")        .POST(BodyPublishers.ofFile(Paths.get("file.json")))        .build();   client.sendAsync(request, BodyHandlers.ofString())        .thenApply(HttpResponse::body)        .thenAccept(System.out::println);