Asynchronous REST services with Jersey 2.26+

As you know, Java EE 8 has been released with the JAX-RS 2.1 (JSR 370) specification supporting asynchronous non-blocking REST services.

This is a great improvement to the API going together with Reactive streams, which were added to recently released Java 9. This has been greatly expected as it can improve the availability of our Java web servers a lot.

Jersey 2.26 is out implementing the JAX-RS 2.1 and you can find a nice getting started guide on their github (https://jersey.github.io/documentation/latest/getting-started.html). The start is quite effortless using the maven archetypes and the Grizzly HTTP server container.

We are going to take a look at an example of how implementing an Async response looks like:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Root resource (exposed at "asyncresource" path)
 */
@Path("asyncresource")
public class AsyncResource {

    /**
     * A method handling HTTP GET requests asynchronously
     *
     * @return A text/plain response string
     */
    @GET
    public void asyncReq(@Suspended AsyncResponse ar) {
        ExecutorService executor = Executors.newFixedThreadPool(3);

        executor.submit(() -> {
            try {
                Thread.sleep(5000);
                ar.resume("Hi. the task is finished. Getting back to you!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("Returns immediately.");
    }
}

The @Path annotation denotes the url suffix the service is accessible through. So far nothing new and exceptional. The change comes with the AsyncResponse, which is injected using the @Suspended annotation. This causes a return from this method immediately, but sends the response only after a long running task has finished its execution via ar.resume().

You need an ExecutorService to run the task in a separate thread. More information about the ExecutorService can be found in JSR 236 - Concurrency Utilities for Java EE.

You can find more information regarding the capabilities of the REST web services of JAVA EE 8 in the specification (https://www.jcp.org/en/jsr/detail?id=370)

I hope this will get you started quickly with asynchronous JAX-RS services. Follow us for more examples.