Tuesday, October 27, 2015

Building Asynchronous RESTful Services With Spring MVC and Guava

Recently I was working some asynchronous RESTful services in the Spring MVC framework in which i am thinking of using Guava to reduce the effort in development. After failing to find any good reference on using Guava with Spring MVC's asynchronous RESTful operation, I decide to do it by trial and error. In the end, it turned out to be quite easy. This post shows how to develop asynchronous RESTful services with spring mvc and google's Guava library.

Firstly includes the dependencies for Guava in your spring MVC project.

Implementation using Guava in Spring MVC

Now write a simple spring service something like the one below:

import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

public class MyLongRunningServiceImpl extends MyLongRunningService {
   private ListeningExecutorService service;
   public MyLongRunningService(){
     service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));

   public ListenableFuture<Date> doLongRunningProcess(final int milliseconds){
 ListenableFuture<date> future = service.submit(new Callable<date>() {
            public Date call() throws Exception {
                return new Date();

 return future;

As shown in the code above the service has a method which delay a number user-specified milliseconds before returning a Date object. Next write a simple controller that autowires with the service:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.async.DeferredResult;

public class MyLongRunningController {
  private MyLongRunningService service;

  @RequestMapping(value="/longRun", method = RequestMethod.GET)
 public @ResponseBody DeferredResult<Date> doLongRunningProcess(){
  DeferredResult<Date> deferredResult = new DeferredResult<>();

  logger.info("start long running process");
  ListenableFuture<Date> future = service.doLongRunningProcess(60000);
  Futures.addCallback(future, new FutureCallback<Date>(){

   public void onFailure(Throwable throwable) {
    logger.error("long running process failed", throwable);


   public void onSuccess(Date res) {
    logger.info("long running process returns");
  return deferredResult;

This completes the coding part. There are two notes apart from the above implementation in order to make the asynchronous RESTful service to work:


The first thing is that the user needs to add in the following XML element into their web.xml configuration


This should be put under both <servlet> section (for the servlet which contains the spring controller above) as well as the <filter> section of the "org.springframework.web.filter.DelegatingFilterProxy"


If you are using Tomcat server as the servlet and http container for your spring MVC, that the asyncTimeout need to be added into the <Connector> element of the /conf/server.xml in tomcat directory, so that async services won't be terminated before tomcat's timeout, e.g.,

<Connector asyncTimeout="60000" ... >

If you are using javascript to interact with the asynchronous RESTful services, you may also need to specify the timeout property (e.g., in the $http of angularjs) so that the http call will not terminate before the asynchronous service call is completed.

No comments:

Post a Comment