2015-07-12 171 views
2

控制器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類= 「org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping」> \t \t <屬性名= 「順序」 的值= 「0」/> \t' 在我的spring applicationContext.xml中。 – tian

回答

0
<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.