{"id":9621,"date":"2013-03-11T19:00:04","date_gmt":"2013-03-11T17:00:04","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=9621"},"modified":"2013-03-11T17:02:04","modified_gmt":"2013-03-11T15:02:04","slug":"deferredresult-asynchronous-processing-in-spring-mvc","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html","title":{"rendered":"DeferredResult &#8211; asynchronous processing in Spring MVC"},"content":{"rendered":"<p><a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/web\/context\/request\/async\/DeferredResult.html\"><code>DeferredResult<\/code><\/a> is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous computation and take advantage of Servlet 3.0 <a href=\"http:\/\/docs.oracle.com\/javaee\/6\/api\/javax\/servlet\/AsyncContext.html\"><code>AsyncContext<\/code><\/a> asynchronous request handling. Just to give a quick impression how it works:<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n<pre class=\"brush:java\">@RequestMapping(\"\/\")\r\n@ResponseBody\r\npublic DeferredResult&lt;String&gt; square() throws JMSException {\r\n    final DeferredResult&lt;String&gt; deferredResult = new DeferredResult&lt;&gt;();\r\n    runInOtherThread(deferredResult);\r\n    return deferredResult;\r\n}\r\n \r\nprivate void runInOtherThread(DeferredResult&lt;String&gt; deferredResult) {\r\n    \/\/seconds later in other thread...\r\n    deferredResult.setResult(\"HTTP response is: 42\");\r\n}<\/pre>\n<p>Normally once you leave controller handler method request processing is done. But not with <code>DeferredResult<\/code>. Spring MVC (using Servlet 3.0 capabilities) will hold on with the response, keeping idle HTTP connection. HTTP worker thread is no longer used, but HTTP connection is still open. Later some other thread will resolve <code>DeferredResult<\/code> by assigning some value to it. Spring MVC will immediately pick up this event and send response (<i>&#8220;HTTP response is: 42&#8221;<\/i> in this example) to the browser, finishing request processing.<\/p>\n<p>You might see some conceptual similarity between <code>Future&lt;V&gt;<\/code> and <code>DeferredResult<\/code> &#8211; they both represent computation with result available some time in the future. You might wonder, why Spring MVC doesn&#8217;t allow us to simply return <code>Future&lt;V&gt;<\/code> but instead introduced new, proprietary abstraction? The reason is simply and once again shows <code>Future&lt;V&gt;<\/code> deficiencies. The whole point of asynchronous processing is avoid blocking threads. Standard <code>java.util.concurrent.Future<\/code> does not allow registering callbacks when computation is done &#8211; so you either need to devote one thread to block until future is done or use one thread to poll several futures periodically. However the latter option consumes more CPU and introduces latency. But <a href=\"http:\/\/nurkiewicz.blogspot.no\/2013\/02\/listenablefuture-in-guava.html\">superior <code>ListenableFuture&lt;V&gt;<\/code><\/a> from <a href=\"http:\/\/code.google.com\/p\/guava-libraries\/\">Guava<\/a> seems like a good fit? True, but Spring doesn&#8217;t have a dependency on Guava, thankfully bridging these two APIs is pretty straightforward.<\/p>\n<p>But first have a look at previous part on <a href=\"http:\/\/nurkiewicz.blogspot.no\/2013\/02\/implementing-custom-future.html\">implementing custom <code>java.util.concurrent.Future&lt;V&gt;<\/code><\/a>. Admittedly it wasn&#8217;t as simple as one might expect. Clean up, handling interruptions, locking and synchronization, maintaining state. A lot of boilerplate when everything we need is as simple as receiving a message and returning it from <code>get()<\/code>. Let us try to retrofit previous implementation of <code>JmsReplyFuture<\/code> to also implement more powerful <code>ListenableFuture<\/code> &#8211; so we can use it later in Spring MVC.<\/p>\n<p><code>ListenableFuture<\/code> simply extends <i>standard<\/i> <code>Future<\/code> adding possibility to register callbacks (listeners). So an eager developer would simply sit down and add list of <code>Runnable<\/code> listeners to existing implementation:<\/p>\n<pre class=\"brush:java\">public class JmsReplyFuture&lt;T extends Serializable&gt; implements ListenableFuture&lt;T&gt;, MessageListener {\r\n \r\n    private final List&lt;Runnable&gt; listeners = new ArrayList&lt;Runnable&gt;();\r\n \r\n    @Override\r\n    public void addListener(Runnable listener, Executor executor) {\r\n        listeners.add(listener);\r\n    }\r\n \r\n    \/\/...<\/pre>\n<p>But it&#8217;s greatly oversimplified. Of course we must iterate over all listeners when future is done or exception occurs. If the future is already resolved when we add a listener, we must call that listener immediately. Moreover we ignore <code>executor<\/code> &#8211; according to API each listener may use a different thread pool supplied to <code>addListener()<\/code> so we must store pairs: <code>Runnable<\/code> + <code>Executor<\/code>. Last but not least <code>addListener()<\/code> is not thread safe. Eager developer would fix all this in a matter of an hour or two. And spend two more hours to fix bugs introduced in the meantime. And few more hours weeks later when another &#8220;impossible&#8221; bug pops-up on production. I am not eager. As a matter of fact, I am too lazy to write even the simplest implementation above. But I am desperate enough to hit <code>Ctrl<\/code> + <code>H<\/code> (<i>Subtypes<\/i> view in IntelliJ IDEA) on <code>ListenableFuture<\/code> and scan through available skeletal implementations tree. <a href=\"http:\/\/docs.guava-libraries.googlecode.com\/git\/javadoc\/com\/google\/common\/util\/concurrent\/AbstractFuture.html\"><code>AbstractFuture&lt;V&gt;<\/code><\/a> &#8211; Bingo!<\/p>\n<pre class=\"brush:java\">public class JmsReplyListenableFuture&lt;T extends Serializable&gt; extends AbstractFuture&lt;T&gt; implements MessageListener {\r\n \r\n    private final Connection connection;\r\n    private final Session session;\r\n    private final MessageConsumer replyConsumer;\r\n \r\n    public JmsReplyListenableFuture(Connection connection, Session session, Queue replyQueue) throws JMSException {\r\n        this.connection = connection;\r\n        this.session = session;\r\n        this.replyConsumer = session.createConsumer(replyQueue);\r\n        this.replyConsumer.setMessageListener(this);\r\n    }\r\n \r\n    @Override\r\n    public void onMessage(Message message) {\r\n        try {\r\n            final ObjectMessage objectMessage = (ObjectMessage) message;\r\n            final Serializable object = objectMessage.getObject();\r\n            set((T) object);\r\n            cleanUp();\r\n        } catch (Exception e) {\r\n            setException(e);\r\n        }\r\n    }\r\n \r\n    @Override\r\n    protected void interruptTask() {\r\n        cleanUp();\r\n    }\r\n \r\n    private void cleanUp() {\r\n        try {\r\n            replyConsumer.close();\r\n            session.close();\r\n            connection.close();\r\n        } catch (Exception e) {\r\n            Throwables.propagate(e);\r\n        }\r\n    }\r\n}<\/pre>\n<p>That&#8217;s it, everything, compile and run. Almost 2x less code compared to <a href=\"http:\/\/nurkiewicz.blogspot.no\/2013\/02\/implementing-custom-future.html\">initial implementation<\/a> and we get much more powerful <code>ListenableFuture<\/code>. Most of the code is set up and clean up. <code>AbstractFuture<\/code> already implements <code>addListener()<\/code>, locking and state handling for us. All we have to do is call <code>set()<\/code> method when future is resolved (JMS reply arrives in our case). Moreover we finally support exceptions properly. Previously we simply ignored\/rethrown them while now they are correctly wrapped and thrown from <code>get()<\/code> when accessed. Even if we weren&#8217;t interested in <code>ListenableFuture<\/code> capabilities, <code>AbstractFuture<\/code> still helps us a lot. And we get <code>ListenableFuture<\/code> for free.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>Good programmers love writing code. Better ones <a href=\"http:\/\/devopsreactions.tumblr.com\/post\/44360857123\">love <i>deleting<\/i> it<\/a>. Less to maintain, less to test, less to break. I am sometimes amazed how helpful Guava can be. Last time I was working with iterator-heavy piece of code. Data was generated dynamically and iterators could easily produce millions of items so I had no choice. Limited iterator API together with quite complex business logic is a recipe for endless amount of plumbing code. And then I found <a href=\"http:\/\/docs.guava-libraries.googlecode.com\/git\/javadoc\/com\/google\/common\/collect\/Iterators.html\"><code>Iterators<\/code> utility class<\/a> and it saved my life. I suggest you to open <a href=\"http:\/\/docs.guava-libraries.googlecode.com\/git\/javadoc\/index.html\">JavaDoc of Guava<\/a> and go through all packages, class by class. You&#8217;ll thank me later.<\/p>\n<p>Once we have our custom <code>ListenableFuture<\/code> in place (obviously you can use any implementation) we can try integrating it with Spring MVC. Here is what we want to achieve:<\/p>\n<ol>\n<li>HTTP request comes in<\/li>\n<li>We send a request to JMS queue<\/li>\n<li>HTTP worker thread is no longer used, it can serve other requests<\/li>\n<li>JMS listener asynchronously waits for a reply in temporary queue<\/li>\n<li>Once the reply arrives we push it immediately as an HTTP response and the connection is done.<\/li>\n<\/ol>\n<p>First naive implementation using blocking <code>Future<\/code>:<\/p>\n<pre class=\"brush:java\">@Controller\r\npublic class JmsController {\r\n \r\n    private final ConnectionFactory connectionFactory;\r\n \r\n    public JmsController(ConnectionFactory connectionFactory) {\r\n        this.connectionFactory = connectionFactory;\r\n    }\r\n \r\n    @RequestMapping(\"\/square\/{value}\")\r\n    @ResponseBody\r\n    public String square(@PathVariable double value) throws JMSException, ExecutionException, InterruptedException {\r\n        final ListenableFuture&lt;Double&gt; responseFuture = request(value);\r\n        return responseFuture.get().toString();\r\n    }\r\n \r\n    \/\/JMS API boilerplate\r\n    private &lt;T extends Serializable&gt; ListenableFuture&lt;T&gt; request(Serializable request) throws JMSException {\r\n        Connection connection = this.connectionFactory.createConnection();\r\n        connection.start();\r\n        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);\r\n        final Queue tempReplyQueue = session.createTemporaryQueue();\r\n        final ObjectMessage requestMsg = session.createObjectMessage(request);\r\n        requestMsg.setJMSReplyTo(tempReplyQueue);\r\n        sendRequest(session.createQueue(\"square\"), session, requestMsg);\r\n        return new JmsReplyListenableFuture&lt;T&gt;(connection, session, tempReplyQueue);\r\n    }\r\n \r\n    private void sendRequest(Queue queue, Session session, ObjectMessage requestMsg) throws JMSException {\r\n        final MessageProducer producer = session.createProducer(queue);\r\n        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);\r\n        producer.send(requestMsg);\r\n        producer.close();\r\n    }\r\n \r\n}<\/pre>\n<p>This implementation is not very fortunate. As a matter of fact we don&#8217;t need <code>Future<\/code> at all as we are barely blocking on <code>get()<\/code>, synchronously waiting for a response. Let&#8217;s try with <code>DeferredResult<\/code>:<\/p>\n<pre class=\"brush:java\">@RequestMapping(\"\/square\/{value}\")\r\n@ResponseBody\r\npublic DeferredResult&lt;String&gt; square(@PathVariable double value) throws JMSException {\r\n    final DeferredResult&lt;String&gt; deferredResult = new DeferredResult&lt;&gt;();\r\n    final ListenableFuture&lt;Double&gt; responseFuture = request(value);\r\n    Futures.addCallback(responseFuture, new FutureCallback&lt;Double&gt;() {\r\n        @Override\r\n        public void onSuccess(Double result) {\r\n            deferredResult.setResult(result.toString());\r\n        }\r\n \r\n        @Override\r\n        public void onFailure(Throwable t) {\r\n            deferredResult.setErrorResult(t);\r\n        }\r\n    });\r\n    return deferredResult;\r\n}<\/pre>\n<p>Much more complex, but will also be much more scalable. This method takes almost no time to execute and HTTP worker thread is shortly after ready to handle another request. The biggest observation to make is that <code>onSuccess()<\/code> and <code>onFailure()<\/code> are executed by another thread, seconds or even minutes later. But HTTP worker thread pool is not exhausted and application remains responsive.<\/p>\n<p>This was a school book example, but can we do better? First attempt is to write generic adapter from <code>ListenableFuture<\/code> to <code>DeferredResult<\/code>. These two abstractions represent exactly the same thing, but with different API. It&#8217;s quite straightforward:<\/p>\n<pre class=\"brush:java\">public class ListenableFutureAdapter&lt;T&gt; extends DeferredResult&lt;String&gt; {\r\n \r\n    public ListenableFutureAdapter(final ListenableFuture&lt;T&gt; target) {\r\n        Futures.addCallback(target, new FutureCallback&lt;T&gt;() {\r\n            @Override\r\n            public void onSuccess(T result) {\r\n                setResult(result.toString());\r\n            }\r\n \r\n            @Override\r\n            public void onFailure(Throwable t) {\r\n                setErrorResult(t);\r\n            }\r\n        });\r\n    }\r\n}<\/pre>\n<p>We simply extend <code>DeferredResult<\/code> and notify it using <code>ListenableFuture<\/code> callbacks. Usage is simple:<\/p>\n<pre class=\"brush:java\">@RequestMapping(\"\/square\/{value}\")\r\n@ResponseBody\r\npublic DeferredResult&lt;String&gt; square(@PathVariable double value) throws JMSException {\r\n    final ListenableFuture&lt;Double&gt; responseFuture = request(value);\r\n    return new ListenableFutureAdapter&lt;&gt;(responseFuture);\r\n}<\/pre>\n<p>But we can do even better! If <code>ListenableFuture<\/code> and <code>DeferredResult<\/code> are so similar, why not simply return <code>ListenableFuture<\/code> from the controller handler method?<\/p>\n<pre class=\"brush:java\">@RequestMapping(\"\/square\/{value}\")\r\n@ResponseBody\r\npublic ListenableFuture&lt;Double&gt; square2(@PathVariable double value) throws JMSException {\r\n    final ListenableFuture&lt;Double&gt; responseFuture = request(value);\r\n    return responseFuture;\r\n}<\/pre>\n<p>Well, it won&#8217;t work because Spring doesn&#8217;t understand <code>ListenableFuture<\/code> and will just blow up. Fortunately Spring MVC is very flexible and it allows us to easily register new <i>so-called<\/i> <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/web\/method\/support\/HandlerMethodReturnValueHandler.html\"><code>HandlerMethodReturnValueHandler<\/code><\/a>. There are 12 such built-in handlers and every time we return some object from a controller, Spring MVC examines them in predefined order and chooses the first one that can handle given type. One such handler is <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/web\/context\/request\/async\/DeferredResult.DeferredResultHandler.html\"><code>DeferredResultHandler<\/code><\/a> (name says it all) which we will use as a reference:<\/p>\n<pre class=\"brush:java\">public class ListenableFutureReturnValueHandler implements HandlerMethodReturnValueHandler {\r\n \r\n    public boolean supportsReturnType(MethodParameter returnType) {\r\n        Class&lt;?&gt; paramType = returnType.getParameterType();\r\n        return ListenableFuture.class.isAssignableFrom(paramType);\r\n    }\r\n \r\n    public void handleReturnValue(Object returnValue,\r\n                                  MethodParameter returnType, ModelAndViewContainer mavContainer,\r\n                                  NativeWebRequest webRequest) throws Exception {\r\n \r\n        if (returnValue == null) {\r\n            mavContainer.setRequestHandled(true);\r\n            return;\r\n        }\r\n \r\n        final DeferredResult&lt;Object&gt; deferredResult = new DeferredResult&lt;&gt;();\r\n        Futures.addCallback((ListenableFuture&lt;?&gt;) returnValue, new FutureCallback&lt;Object&gt;() {\r\n            @Override\r\n            public void onSuccess(Object result) {\r\n                deferredResult.setResult(result.toString());\r\n            }\r\n \r\n            @Override\r\n            public void onFailure(Throwable t) {\r\n                deferredResult.setErrorResult(t);\r\n            }\r\n        });\r\n        WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(deferredResult, mavContainer);\r\n    }\r\n \r\n}<\/pre>\n<p>Running out of karma, installing this handler is not as straightforward as I had hoped. Technically there is <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/web\/servlet\/config\/annotation\/WebMvcConfigurerAdapter.html#addReturnValueHandlers%28java.util.List%29\"><code>WebMvcConfigurerAdapter.addReturnValueHandlers()<\/code><\/a> which we can easily override if using Java configuration for Spring MVC. But this method adds custom return value handler at the end of handlers chain and for reasons beyond the scope of this article we need to add it at the beginning (higher priority). Fortunately with a little bit of hacking we can achieve that as well:<\/p>\n<pre class=\"brush:java\">@Configuration\r\n@EnableWebMvc\r\npublic class SpringConfig extends WebMvcConfigurerAdapter {\r\n \r\n    @Resource\r\n    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;\r\n \r\n    @PostConstruct\r\n    public void init() {\r\n        final List&lt;HandlerMethodReturnValueHandler&gt; originalHandlers = new ArrayList&lt;&gt;(requestMappingHandlerAdapter.getReturnValueHandlers().getHandlers());\r\n        originalHandlers.add(0, listenableFutureReturnValueHandler());\r\n        requestMappingHandlerAdapter.setReturnValueHandlers(originalHandlers);\r\n    }\r\n \r\n    @Bean\r\n    public HandlerMethodReturnValueHandler listenableFutureReturnValueHandler() {\r\n        return new ListenableFutureReturnValueHandler();\r\n    }\r\n \r\n}<\/pre>\n<h2>Summary<\/h2>\n<p>In this article we familiarized ourselves with another incarnation of future\/promise abstraction called <code>DeferredResult<\/code>. It is used to postpone handling of HTTP request until some asynchronous task finishes. Thus <code>DeferredResult<\/code> is great for web GUIs built on top of event-driven systems, message brokers, etc. It is not as powerful as raw Servlet 3.0 API though. For example we cannot stream multiple events as they arrive (e.g. new tweets) in long-running HTTP connection &#8211; Spring MVC is designed more toward request-response pattern.<\/p>\n<p>We also tweaked Spring MVC to allow returning <code>ListenableFuture<\/code> from Guava directly from controller method. It makes our code much cleaner and expressive.<br \/>\n&nbsp;<\/p>\n<p><b><i>Reference: <\/i><\/b><a href=\"http:\/\/nurkiewicz.blogspot.gr\/2013\/03\/deferredresult-asynchronous-processing.html\">DeferredResult &#8211; asynchronous processing in Spring MVC<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Tomasz Nurkiewicz at the <a href=\"http:\/\/nurkiewicz.blogspot.com\/\">NoBlogDefFound<\/a> blog.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous computation and take advantage of Servlet 3.0 AsyncContext asynchronous request handling. Just to give a quick impression how it works: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @RequestMapping(&#8220;\/&#8221;) @ResponseBody public DeferredResult&lt;String&gt; square() throws JMSException &hellip;<\/p>\n","protected":false},"author":13,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[30,150],"class_list":["post-9621","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-spring","tag-spring-mvc"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>DeferredResult - asynchronous processing in Spring MVC<\/title>\n<meta name=\"description\" content=\"DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DeferredResult - asynchronous processing in Spring MVC\" \/>\n<meta property=\"og:description\" content=\"DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2013-03-11T17:00:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Tomasz Nurkiewicz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/tnurkiewicz\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Tomasz Nurkiewicz\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html\"},\"author\":{\"name\":\"Tomasz Nurkiewicz\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fb1be85725c10e8361e641fa851e79e1\"},\"headline\":\"DeferredResult &#8211; asynchronous processing in Spring MVC\",\"datePublished\":\"2013-03-11T17:00:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html\"},\"wordCount\":1224,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Spring\",\"Spring MVC\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html\",\"name\":\"DeferredResult - asynchronous processing in Spring MVC\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2013-03-11T17:00:04+00:00\",\"description\":\"DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/03\\\/deferredresult-asynchronous-processing-in-spring-mvc.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"DeferredResult &#8211; asynchronous processing in Spring MVC\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fb1be85725c10e8361e641fa851e79e1\",\"name\":\"Tomasz Nurkiewicz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"caption\":\"Tomasz Nurkiewicz\"},\"description\":\"Java EE developer, Scala enthusiast. Enjoying data analysis and visualization. Strongly believes in the power of testing and automation.\",\"sameAs\":[\"http:\\\/\\\/nurkiewicz.blogspot.com\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/tnurkiewicz\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/tomasz-nurkiewicz\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"DeferredResult - asynchronous processing in Spring MVC","description":"DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html","og_locale":"en_US","og_type":"article","og_title":"DeferredResult - asynchronous processing in Spring MVC","og_description":"DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous","og_url":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2013-03-11T17:00:04+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Tomasz Nurkiewicz","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/tnurkiewicz","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Tomasz Nurkiewicz","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html"},"author":{"name":"Tomasz Nurkiewicz","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fb1be85725c10e8361e641fa851e79e1"},"headline":"DeferredResult &#8211; asynchronous processing in Spring MVC","datePublished":"2013-03-11T17:00:04+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html"},"wordCount":1224,"commentCount":2,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Spring","Spring MVC"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html","url":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html","name":"DeferredResult - asynchronous processing in Spring MVC","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2013-03-11T17:00:04+00:00","description":"DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/03\/deferredresult-asynchronous-processing-in-spring-mvc.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"DeferredResult &#8211; asynchronous processing in Spring MVC"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fb1be85725c10e8361e641fa851e79e1","name":"Tomasz Nurkiewicz","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","caption":"Tomasz Nurkiewicz"},"description":"Java EE developer, Scala enthusiast. Enjoying data analysis and visualization. Strongly believes in the power of testing and automation.","sameAs":["http:\/\/nurkiewicz.blogspot.com\/","https:\/\/x.com\/https:\/\/twitter.com\/tnurkiewicz"],"url":"https:\/\/www.javacodegeeks.com\/author\/tomasz-nurkiewicz"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/9621","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=9621"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/9621\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=9621"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=9621"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=9621"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}