JAX-RS - Asynchronous Processing

[Updated: Aug 24, 2017, Created: Aug 24, 2017]

All RAX-RS resource methods should return the response quickly otherwise the processing thread will block for the entire time which is supposed to be returned to the underlying container's thread pool as soon as possible to serve the other requests.

JAX-RS specification provides a mechanism to handle long running resources. This mechanism involves injecting an AsyncResponse instance (as resource/sub-resource method parameter) by using @Suspended annotation.

AsyncResponse provides methods to update the state of asynchronous processing so that the underlying implementation can take an appropriate action. The resource method is called with the AsyncResponse instance in a suspended state. The client code, after running the long process, must call AsyncResponse.resume(), so that a response can be sent back to the client.

The resource method annotated with @Suspended is not called in a separate thread. It is the developer responsibility to create a new thread for the long running process and return the caller thread quickly.

Example

A resource with async processing

@Path("/orders")
public class OrderResource {

  @GET
  public void getAllOrders(@Suspended final AsyncResponse ar) {
      System.out.println("-- getAllOrders() resource method --");
      System.out.println("AsyncResponse#suspended=" + ar.isSuspended());

      ExecutorService es = Executors.newSingleThreadExecutor();
      es.submit(() -> {
          try {
              //Simulating a long running process
              Thread.sleep(2000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          ar.resume("all orders data....");
          es.shutdown();
      });
  }
}

The resource client

public class OrderClient {
  public static void main(String[] args) throws Exception {
      Client client = ClientBuilder.newBuilder().build();
      WebTarget target =
              client.target("http://localhost:8080/orders");
      long start = System.currentTimeMillis();
      Response response = target.request().get(Response.class);
      String responseString = response.readEntity(String.class);
      System.out.println("response: " + responseString);
      System.out.println("time taken: " + (System.currentTimeMillis() - start));
      System.out.println("main method exits");
  }
}

Output

response: all orders data....
time taken: 2594
main method exits

Example Project

Dependencies and Technologies Used :

  • jersey-server 2.25.1: Jersey core server implementation.
  • jersey-container-servlet 2.25.1: Jersey core Servlet 3.x implementation.
  • JDK 1.8
  • Maven 3.3.9

Asynchronous Processing Example Select All Download
  • jaxrs-asynchronous-processing
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also