Spring MVC DeferredResult异步请求不起作用,异步请求立即响应

时间:2015-07-12 15:44:47

标签: spring spring-mvc asynchronous

控制器

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 [farm.controller.DeferredController@ab2d774] 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 [org.springframework.web.context.request.async.DeferredResult@420d10a7] as "text/html" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@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请求时,响应结果会在一秒内立即返回,我不知道是否有错误配置,而且我花了一整天的时间处理它。

1 个答案:

答案 0 :(得分: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.