Deferred Result in Spring MVC returning incorrect response

The response body you are getting

{"setOrExpired":true}

indicates that Spring serialized your DeferredResult (which has various properties including setOrExpired) to JSON instead of handling it with a DeferredResultMethodReturnValueHandler. In other words, it used another HandlerMethodReturnValueHandler, most likely RequestResponseBodyMethodProcessor (which handles @ResponseBody), to handle the value returned from your @RequestMapping annotated handler method. (The simplest way to test this is to see what happens when you remove the @ResponseBody annotation.)

Looking at the 3.2.x source code of RequestMappingHandlerAdapter, which registers the default HandlerMethodReturnValueHandler instances, the DeferredResultMethodReturnValueHandler is registered before RequestResponseBodyMethodProcessor and therefore will handle the DeferredResult return value first.

Since you're seeing different behavior, we must assume your configuration is not what you've shown here. (Note that <mvc:annotation-driven/> registers a RequestMappingHandlerAdapter.)


Also note that you are currently loading the configuration in /WEB-INF/app-servlet.xml twice, once by the ContextLoaderListener and once by the DispatcherServlet.

Get rid of your ContextLoaderListener and the corresponding context-param entirely. They are not needed in your example.


I know is impossible to be the problem in this case (spring mvc 3.2.4) but just for future references: I get the same issue with spring boot 2.2.0.BUILD-SNAPSHOT (spring 5.1.5). This error happens when you try to return DeferredResult using webflux instead of the traditional spring mvc app. Remember, in the new webflux api you should use mono/flux, not DeferredResult.