I'm fairly new to Java, so this may seem obvious to some. I've worked a lot with ActionScript, which is very much event based and I love that. I recently tried to write a small bit of Java code that does a POST request, but I've been faced with the problem that it's a synchronous request, so the code execution waits for the request to complete, time out or present an error.
How can I create an asynchronous request, where the code continues the execution and a callback is invoked when the HTTP request is complete? I've glanced at threads, but I'm thinking it's overkill.
Overview. AsyncHttpClient (AHC) is a library build on top of Netty, with the purpose of easily executing HTTP requests and processing responses asynchronously. In this article, we'll present how to configure and use the HTTP client, how to execute a request and process the response using AHC.
There are multiple ways to do Async programming in Java, starting from Thread, Runnable, Callable<T>, Future<T> (and its extended ScheduledFuture<T>), CompletableFuture<T>, and of course, ExecutorService and ForkJoinPool. Java concurrency is the functionality that enables asynchronous programming in Java.
Asynchronous HTTP Request Processing is a relatively new technique that allows you to process a single HTTP request using non-blocking I/O and, if desired in separate threads. Some refer to it as COMET capabilities.
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.
You may also want to look at Async Http Client.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With