Spring MVC 3.2 Preview: Making a Controller Method Asynchronous

Engineering | Rossen Stoyanchev | May 10, 2012 | ...

Last updated on November 5th, 2012 (Spring MVC 3.2 RC1)

In previous posts I introduced the Servlet 3 based async capability in Spring MVC 3.2 and discussed techniques for real-time updates. In this post I'll go into more technical details and discuss how asynchronous processing fits into the Spring MVC request lifecycle.

As a quick reminder, you can make any existing controller method asynchronous by changing it to return a Callable. For example a controller method that returns a view name, can return Callable<String> instead. An @ResponseBody that returns an object called Person can return Callable<Person> instead. And the same is true for any other controller return value type.

A central idea is that all of what you already know about how a controller method works remains unchanged as much as possible except that the remaining processing will occur in another thread. When it comes to asynchronous execution it's important to keep things simple. As you'll see even with this seemingly simple programming model change, there is quite a bit to consider.

The spring-mvc-showcase has been updated for Spring MVC 3.2. Have a look at CallableController. Method annotations like @ResponseBody and @ResponseStatus apply to the return value from the Callable as well, as you might expect. Exceptions raised from a Callable are handled as if they were raised by the controller, in this case with an @ExceptionHandler method. And so on.

If you execute one of the CallableController methods through the "Async Requests" tab in the browser, you should see output similar to the one below:

08:25:15 [http-bio-8080-exec-10] DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for [...]
08:25:15 [http-bio-8080-exec-10] RequestMappingHandlerMapping - Looking up handler method for path /async/callable/view
08:25:15 [http-bio-8080-exec-10] RequestMappingHandlerMapping - Returning handler method [...]
08:25:15 [http-bio-8080-exec-10] WebAsyncManager - Concurrent handling starting for GET [...]
08:25:15 [http-bio-8080-exec-10] DispatcherServlet - Leaving response open for concurrent…

Using Cloud Foundry Workers with Spring

Engineering | Josh Long | May 09, 2012 | ...

You've no doubt read Jennifer Hickey's amazing blog posts introducing Cloud Foundry workers, their application in setting up Ruby Resque background jobs, and today's post introducing the Spring support.

Key Takeaways for Spring Developers

  1. You need to update your version of vmc with gem update vmc.
  2. Cloud Foundry workers let you run public static void main jobs. That is, a Cloud Foundry worker is basically a process, lower level than a web application, which maps naturally to many so-called back-office jobs.
  3. You need to provide the command that Cloud Foundry will run. You could provide the java incantation you'd like it to use, but it's far simpler to ship a shell script, and have Cloud Foundry run that shell script for you, instead. The command you provide should employ $JAVA_OPTS, which Cloud Foundry has already provided to ensure consistent memory usage and JVM settings.
  4. There are various ways to automate the creation of a Cloud Foundry deployable application. If you're using Maven, then the org.codehaus.mojo:appassembler-maven-plugin plugin will help you create a startup script and package your .jars for easy deployment, as well as specifying an entry point class.
  5. Everything else is basically the same. When you do vmc push on a Java .jar project, Cloud Foundry will ask you whether the application is a standalone application. Confirm, and it'll walk you through the setup from there.

So, let's look at a few common architectures and arrangements that are easier and more natural with Cloud Foundry workers. We'll look at these patterns in terms of the Spring framework and two surrounding projects, Spring Integration and Spring Batch, both of which thrive in, and outside of, web applications. As we'll see, both of these frameworks support decoupling and improved composability. We'll disconnect what happens from when it happens, and we'll disconnect what happens from where it happens, both in the name of freeing up capacity on the front end.

I've got a Schedule to Keep!

One common question I get is: How do I do job scheduling on Cloud Foundry? Cloud Foundry supports Spring applications, and Spring of course has always supported enterprise grade scheduling abstractions like Quartz and Spring 3.0's @Scheduled annotation. @Scheduled is really nice because it is super easy to add into an existing application. In the simplest case, you add @EnableScheduling to your Java configuration or <task:annotation-driven/> to your XML, and then use the @Scheduled annotation in your code. This is a very natural thing to do in an enterprise application - perhaps you have an analytics or reporting process that needs to run? Some long running batch process? I've put together an example that demonstrates using @Scheduled to run a Spring Batch Job. The Spring Batch job itself is a worker thread that works with a web service whose poor SLA make it unfit for realtime use. It's safer, and cleaner, to handle the work in Spring Batch, where its recovery and retry capabilities pick up the slack of any network outages, network latency, etc. I'll refer you to the code example for most of the details, we'll just look at the the entry point and then look at deploying the application to Cloud Foundry.

					    
// set to every 10s for testing.
@Scheduled(fixedRate = 10 * 1000)
public void runNightlyStockPriceRecorder() throws Throwable {
	JobParameters params = new JobParametersBuilder()
		.addDate("date", new Date())
		.toJobParameters();
	JobExecution jobExecution = jobLauncher.run(job, params);
	BatchStatus batchStatus = jobExecution.getStatus();
	while (batchStatus.isRunning()) {
		logger.info("Still running...");
		Thread.sleep(1000);
	}
	logger.info(String.format("Exit status: %s", jobExecution.getExitStatus().getExitCode()));
	JobInstance jobInstance = jobExecution.getJobInstance…

Spring MVC 3.2 Preview: Techniques for Real-time Updates

Engineering | Rossen Stoyanchev | May 08, 2012 | ...

Last updated on November 5th, 2012 (Spring MVC 3.2 RC1)

In my last post I introduced the new Servlet 3 based, async support in Spring MVC 3.2 and talked about long-running requests. A second very important motivation for async processing is the need for browsers to receive real-time updates. Examples include chatting in a browser, stock quotes, status updates, live sports results, and others. To be sure not all examples are equally delay-sensitive but all of them share a similar need.

In standard HTTP request-response semantics a browser initiates a request and the server sends a response, which means the server can't send new information until it has a request from the browser. Several approaches have evolved including traditional polling, long polling, and HTTP streaming and most recently we have the WebSocket protocol.

Traditional Polling

The browser keeps sending requests to check for new information and the server responds immediately each time. This fits scenarios where polling can be done at reasonably sparse intervals. For example a mail client can check for new messages every 10 minutes. It's simple and it works. However, the approach becomes inefficient when new information must be shown as soon as possible in which case polling must be very frequent.

Long Polling

The browser keeps sending requests but the server doesn't respond until it has new information to send. From a client perspective this is identical to traditional polling. From a server perspective this is very similar to a long-running request and can be scaled using the technique discussed in Part 1.

How long can the response remain open? Browsers are set to time out after 5 minutes and network intermediaries such as proxies can time out even sooner. So even if no new information arrives, a long polling request should complete regularly to allow the browser to send a new request. This IETF document recommends using a timeout value between 30 and 120 seconds but the actual value to use will likely depend on how much control you have over network intermediaries that separate the browser from server.

Long polling can dramatically reduce the number of requests required to receive information updates with low latency, especially where new information becomes available at irregular intervals. However, the more frequent the updates are the closer it gets to traditional polling.

HTTP Streaming

The browser sends a request to the server and the server responds when it has information to send. However, unlike long polling, the server keeps the response open and continues to send more updates as they arrive. The approach removes the need for polling but is also a more significant departure from typical HTTP request-response semantics. For example the client and server need to agree how to interpret the response stream so that the client will know where one update ends and another begins. Furthermore, network intermediaries can cache the response stream which thwarts the intent of the approach. This is why long polling is more commonly used today.

WebSocket Protocol

The browser sends an HTTP request to the server to switch to the WebSocket protocol and the server responds by confirming the upgrade. Thereafter browser and server can send data frames in both directions over a TCP socket.

The WebSocket protocol was designed to replace the need for polling and is specifically suited for scenarios where messages need to be exchanged between browser and server at a high frequency. The initial handshake over HTTP ensures WebSocket requests can go through firewalls. However, there are also significant challenges since a majority of deployed browsers do not support WebSockets and there are further issues with getting through network intermediaries.

WebSockets revolves around the two way exchange of text or binary messages. It leads to a significantly different approach from a RESTful, HTTP-based architecture. In fact there is a need for some another protocol on top of WebSockets, e.g. XMPP, AMQP, STOMP, or other and which one(s) will become predominant remains to be seen.

The WebSocket protocol is already standardized by the IETF while the WebSocket API is in the final stages of being standardized by W3C. A number of Java implementations have become available including servlet containers like Jetty and Tomcat. The Servlet 3.1 spec will likely support the initial WebSocket upgrade request while a separate JSR-356 will define a Java-based WebSocket API.

Coming back to Spring MVC 3.2, the Servlet 3 async feature can be used for long-running requests and also for HTTP streaming, techniques Filip Hanik referred to as "the server version of client AJAX calls". As for WebSockets, there is no support yet in Spring 3.2 but it will most likely be included in Spring 3.3. You can watch SPR-9356 for progress updates.

The next post turns to sample code and explains in more detail the new Spring MVC 3.2 feature.

Spring MVC 3.2 Preview: Introducing Servlet 3, Async Support

Engineering | Rossen Stoyanchev | May 07, 2012 | ...

Last updated on November 5th, 2012 (Spring MVC 3.2 RC1)

Overview

Spring MVC 3.2 introduces Servlet 3 based asynchronous request processing. This is the first of several blog posts covering this new capability and providing context in which to understand how and why you would use it.

The main purpose of early releases is to seek feedback. We've received plenty of it both here and in JIRA since this was first posted after the 3.2 M1 release. Thanks to everyone who gave it a try and commented! There have been numerous changes and there is still time for more feedback!

At a Glance

From a programming model perspective the new capabilities appear deceptively simple. A controller method can now return a java.util.concurrent.Callable to complete processing asynchronously. Spring MVC will then invoke the Callable in a separate thread with the help of a TaskExecutor. Here is a code snippet before:


// Before
@RequestMapping(method=RequestMethod.POST)
public String processUpload(final MultipartFile file) {
    // ...
    return "someView";
}

// After
@RequestMapping(method=RequestMethod.POST)
public Callable<String> processUpload(final MultipartFile file) {

  return new Callable<String>() {
    public Object call() throws Exception {
      // ...
      return "someView";
    }
  };
}

A controller method can also return a DeferredResult (new type in Spring MVC 3.2) to complete processing in a thread not known to Spring MVC. For example reacting to a JMS or an AMQP message, a Redis notification, and so on. Here is another code snippet:


@RequestMapping("/quotes")
@ResponseBody
public DeferredResult<String> quotes() {
  DeferredResult<String> deferredResult…

This Week in Spring, May 1, 2012

Engineering | Josh Long | May 01, 2012 | ...

Welcome to another installment of This Week in Spring! I'm writing the back of the room during Adrian Colyer's amazing keynote at SpringOne On The Road - London event.

  1. Did you guys miss Oleg Zhurakousky's webinar, Practical Tips and Tricks with Spring Integration? Have no fear, the video is available online.

    Also, be sure to check out part 2, this Wednesday, May 3rd for both Europe and North America!

    	</LI>
    	<LI> <a href = "http://blog.springsource.org/author/rclarkson/">Roy Clarkson</A> has announced the <a href = "http://www.springsource.org/spring-mobile/news/1.0.0.rc2-released">latest release of Spring Mobile</A>.  
    		 The release has several enhancements including more refined resolution, and improved site switching behavior. 
    		
    		</LI> 
    		<LI>  <a href = "http://blog.springsource.org/author/jbrisbin/">Jonathan Brisbin</A> just announced <a href="http://blog.springsource.org/author…

This Week in Spring - April 24th, 2012

Engineering | Josh Long | April 24, 2012 | ...

Welcome back to another installment of This Week in Spring! As I compile this, I'm eagerly waiting for Costin Leau to begin his talk on NOSQL with Spring here in sunny, and beautiful Kiev, Ukraine, the first stop in the European leg of the Cloud Foundry Open Tour. The turnout for this event's been staggering! If you're reading this, then you've already missed out on the chance to attend the Kiev event, but be sure to register for the upcoming Moscow and London events.

  1. In this SpringOne 2GX 2011 session, Mark Fisher and Thomas Risberg transform a monolithic enterprise application by changing its relational DB with a NoSQL one, introducing modularity, adding polyglot support and incorporating message queuing and event driven request processing using common enterprise integration patterns.
  2. Did you guys notice that the final edition of the excellent Spring Roo in Action has just been published?
        This book is, as Ben Alex (Spring Roo project founder) put it, "an insightful and comprehensive treatment." I (personally) can't recommend it enough. Ken Rimple and Srini Penchikala, as long time readers of this roundup will know, are frequent Spring community bloggers and 
    

    routinely provide amazing content on all things Spring.

  3. 			 <LI>  
    		Blogger Billy Sj&ouml;berg on DZone has a great post on how <a href = "http://www.dzone.com/links/r/bridging_between_jms_and_rabbitmq_amqp_using_spri.html">to bridge JMS and RabbitMQ</A>. 
    		 This example uses <a href = "http://www.springsource…

This Week in Spring: April 17th, 2012

Engineering | Adam Fitzgerald | April 17, 2012 | ...

Welcome back to another installment of This Week in Spring. This week is the last chance to sign up for the SpringOne on the Road events in London, Kiev and Moscow so be sure to register. Let's dive into it!

  1. Chris Richardson's webinar recording on NoSQL options for the Java developer is online in the SpringSourceDev YouTube Channel.
  2. Shekhar Gulati's excellent introduction to Spring Roo continues over on IBM's developerWorks portal. The latest installment introduces writing advanced (and wrapper) Spring Roo addons.
  3. <LI>  This article, which introduces how to use <a href = "http://java.dzone.com/articles/use-javafx2-spring">Spring to assemble  JavaFX 2 components</a> is short and to the point.  I'd probably use Spring's Java configuration option to fully exploit all the custom components, however. The nice thing about the approach outlined (over using FXML, directly, is that beans configured this way benefit from all the services that Spring provides, including dependency injection and AOP). Nice post, Andy!  </LI>
    
    <LI>Blogger <EM>Rob Gordon</EM> has a nice post introducing <a href ="http://rgordon.co…

This Week in Spring, April 10th, 2012

Engineering | Josh Long | April 11, 2012 | ...

What a great week! The Cloud Foundry Open Tour's well under way, having just finished the Asian and US legs of the tour. Now, onward to Europe! (If you're in Europe, now's the time to secure your spot!)

Before we continue on to the bevy of the latest and greatest content, I wanted to remind you guys to check out Spring Integration ninja Oleg Zhurakousky's upcoming webinar, Practical Tips for Spring Integration. There is, as usual, one event for North America, and one for Europe

  1. Gunnar Hillert's put together a blog introducing a feature that's received a lot of attention in SpringSource Tool Suite: easy-to-use templates for creating Spring Integration projects. Nice job, Gunnar! Also, check out Gunnar's accompanying video Create Spring Integration Projects with STS on the SpringSource YouTube channel.
  2. Michael Isvy has put together a great blog explaining a few of the things you should be aware of when upgrading to Spring 3.1. Handy!
  3.  <LI> Spring Integration 2.1.1 has been released! This is the first maintenance release of 2.1.x branch and contains the usual things like bug fixes and improvements related to AMQP, Gemfire, Mongo and Redis modules which were first introduced in Spring Integration 2.1.0. All together 56 issues were resolved with this release. 
    	 For more, consult <a href = "http://www.springsource.org/node/3520">the release announcement</A>.</LI>
    		
    <LI>  Gabriel Axel talks about the <a href = "http://www.gabiaxel.com/2012/04/spring-social-google-first-milestone-is.html">first milestone of Spring Social…

Create Spring Integration Projects using STS

Engineering | Gunnar Hillert | April 09, 2012 | ...

Just days ago, SpringSource Tool Suite™ (STS) 2.9.1 was released. Besides many new features, it provides several features that are especially exciting for Spring Integration users. First of all, the latest STS release adds support for Spring Integration 2.1 and improves the visualization capabilities for Spring Integration flows. STS supports now all recently added Spring Integration adapters such as:

Also, all existing Spring Integration adapters have been updated to support new visualization elements. Another wonderful addition to Spring Integration users is that SpringSource Tool Suite 2.9.x now ships with templating support for Spring Integration. Thus, when creating a new project using the Spring Template Project Wizard, you can now select between the following 3 new Spring Integration targeted templates:
  • Spring Integration Project (Standalone) - Simple
  • Spring Integration Project (Standalone) - File
  • Spring Integration Project (War)
The Simple template creates a basic Spring Integration project, which runs as a standalone Java application, using only core Spring Integration components. In order to illustrate File polling capabilities, the File template uses additional components to poll file directories as well as to route those files. Lastly, the War template allows users to easily create basic Spring Integration projects that are targeted to run within servlet containers (e.g. Tomcat) as part of a WAR deployment. For illustration purposes the War template uses the Spring Integration Twitter adapter.

Creating a new Spring Integration Project

In order to start a new project using STS Spring Templates, go in the main menu to File, then NEW and then Spring Template Project. The Template Selection Screen will show up next.

 

[caption id="attachment_10681" align="aligncenter" width="342" caption="The Template Selection Screen"][/caption]

This screen provides a list of all available Spring Templates, including the 3 previously mentioned new templates for Spring Integration. If you see that little arrow in front of the template name - that means that the actual template has not been downloaded, yet. Once downloaded, the Templates will be cached on your machine and you won’t need to download the template files again, unless you press the Refresh

This Week in Spring - April 3rd, 2012

Engineering | Josh Long | April 04, 2012 | ...

Welcome to another Installment of This Week in Spring The Cloud Foundry Open Tour is well underway, and have been thus far very good events to attract community.

There are still some (well, there were yesterday!) early bird spots in the upcoming shows in <a href = "http://opentour.cloudfoundry.com/2012/austin">Austin</A>, <a href = "http://opentour.cloudfoundry.com/2012/washington">Washington D.C.</a>, <a href = "http://opentour.cloudfoundry.com/2012/kiev">Kiev</A>, <a href = "http://opentour.cloudfoundry.com/2012/moscow">Moscow</A>, and <a href  = "http://opentour.cloudfoundry.com/2012/london">London</A>, so book now. 

  1. Some of the wonderful content from the Spring I/O conference is now available online! The conference, held in Spain in February of this year, is conducted in both Spanish and English, so there's a lot to like no matter which language you speak. Adrian Colyer's keynote session is super, once you get past the audio problems at the beginning. I couldn't find a SpringIO-specific hash tag, but you can pick them out of the other videos pretty easily by scrolling down. Stay tuned, there should be even more content posted, soon.
  2.  <LI> Tobias Fiohre (who  seemingly lives  <EM>only</Em> to please us, the lucky developers in the  Spring community!)  has put up…

Get the Spring newsletter

Stay connected with the Spring newsletter

Subscribe

Get ahead

VMware offers training and certification to turbo-charge your progress.

Learn more

Get support

Tanzu Spring offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription.

Learn more

Upcoming events

Check out all the upcoming events in the Spring community.

View all