Spring MVC的DeferredResult异步请求不行,异步请求立即响应

问题描述:

控制器Spring MVC的DeferredResult异步请求不行,异步请求立即响应

package farm.controller; 

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.context.request.async.DeferredResult; 


@Controller 
@RequestMapping("/def") 
public class DeferredController { 

    DeferredResult<String> defReq; 


    @RequestMapping("/fasen") 
    @ResponseBody 
    public DeferredResult<String> fasen() { 
     defReq = new DeferredResult<String>(null,"timeout response"); 
     defReq.onCompletion(new Runnable(){ 
      @Override 
      public void run() { 
       System.out.println("after deferredResult completion ..."); 

      } 
     }); 
     return defReq; 
    } 

    @RequestMapping("/loose") 
    public @ResponseBody String loose() { 
     if(defReq!=null) { 
      defReq.setResult("loose Result"); 
      defReq = null; 
      return "loose success"; 
     } else { 
      return "loose not needed"; 
     } 

    } 

} 

的web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    id="WebApp_ID" version="3.0"> 

    <display-name>testfarm</display-name> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath:spring.xml,classpath:spring-mybatis.xml</param-value> 
    </context-param> 

    <filter> 
     <filter-name>encodingFilter</filter-name> 
     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
     <init-param> 
      <param-name>encoding</param-name> 
      <param-value>utf-8</param-value> 
     </init-param> 
     <init-param> 
      <param-name>forceEncoding</param-name> 
      <param-value>true</param-value> 
     </init-param> 
     <async-supported>true</async-supported> 
    </filter> 
    <filter-mapping> 
     <filter-name>encodingFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <!-- 防止spring内存溢出监听器 --> 
    <listener> 
     <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> 
    </listener> 

    <servlet> 
     <description>spring mvc servlet</description> 
     <servlet-name>rest</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value> 
       classpath:spring-mvc.xml 
      </param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
     <async-supported>true</async-supported> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>rest</servlet-name> 
     <url-pattern>*.htmls</url-pattern> 
    </servlet-mapping> 


    <!-- 配置session超时时间,单位分钟 --> 
    <session-config> 
     <session-timeout>30</session-timeout> 
    </session-config> 

    <welcome-file-list> 
     <welcome-file>index.jsp</welcome-file> 
    </welcome-file-list> 
</web-app> 

控制台输出,当我探索网址:http://localhost:8080/master/do/rest/hasMsg.htmls

DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'rest' processing GET request for [/def/fasen.htmls] 
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Matching patterns for request [/def/fasen.htmls] are [/def/fasen.*] 
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - URI Template variables for request [/def/fasen.htmls] are {} 
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapping [/def/fasen.htmls] to HandlerExecutionChain with handler [[email protected]] and 1 interceptor 
DEBUG: org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/def/fasen.htmls] is: -1 
DEBUG: org.springframework.web.bind.annotation.support.HandlerMethodInvoker - Invoking request handler method: public org.springframework.web.context.request.async.DeferredResult farm.controller.DeferredController.fasen() 
DEBUG: org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter - Written [[email protected]d10a7] as "text/html" using [org.springfr[email protected]5168759b] 
DEBUG: org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'rest': assuming HandlerAdapter completed request handling 
DEBUG: org.springframework.web.servlet.DispatcherServlet - Successfully completed request 

当我发送一个http请求,响应结果立即返回一秒钟内,我不知道是什么时候我有错误配置,我花了整整一天处理它。

+0

没有在你的代码看起来像它会花费较长的时间显著量,你有没有尝试添加了Thread.sleep? – xenoterracide

+0

你期望什么行为?为什么? –

+0

很久以后我找到了原因。这是我CONFIG ' \t \t \t' 在我的spring applicationContext.xml中。 – tian

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
    <property name="order" value="0" /> 
</bean> 

不应在applicationContext.xml中配置。在Spring MVC的官方文档,对其理由进行说明是这样的:

Prior to Spring 3.1, type and method-level request mappings were examined 
in two separate stages — a controller was selected first by the DefaultAnnotationHandlerMapping 
and the actual method to invoke was narrowed down second by the AnnotationMethodHandlerAdapter. 

    With the new support classes in Spring 3.1, the RequestMappingHandlerMapping is the 
only place where a decision is made about which method should process the request. 
Think of controller methods as a collection of unique endpoints with mappings for 
each method derived from type and method-level @RequestMapping information.