从spring3.2开始,支持servlet3的异步请求,这对于处理耗时的请求如缓慢的数据库查询是非常有好处的,不至于很快的耗光servlet的线程池,影响可扩展性。
让我们先来了解一下servlet是怎么处理异步操作的:

  1. 通过调用request.startAsync(),ServletRequest就变成异步模式。主要的影响是Servlet、Filter会退出,但是Response保持打开用来完成请求处理。
  2. 调用request.startAsync()返回AsyncContext实例,可进一步控制异步处理。例如,它提供dispatch方法,可
    以从应用线程调用以分发请求回Servlet容器。异步调度和forward的方式是相似的,但是异步调度是由应用线程到Servlet容器线程产生的,
    而forward的方式是同时发生在相同的Servlet容器线程。
  3. ServletRequest提供当前的DispatcherType,它可以用来在异步调度中区分正在处理的初始请求线程是Servlet还是Filter。

接着来看一下callable是怎么处理异步操作的:

  1. Controller返回一个Callable实例;
  2. Spring MVC开始异步处理并在一个单独的线程中,提交Callable实例给TaskExecutor处理;
  3. DispatcherServlet和所有的Filter退出请求线程但是response保存打开;
  4. Callable返回结果,Spring MVC分发请求回Servlet容器;
  5. DispatcherServlet重新调用并继续处理从Callable实例中异步返回的结果。

现在来看一下代码是怎么实现的

1、pom.xml

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.13.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
 

2、applicationContext-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
"> <context:component-scan base-package="com.test"/> <mvc:annotation-driven>
<!-- 配置超时时间 -->
<mvc:async-support default-timeout="3000">
<!-- 这里可以配置callable或者deferred-result拦截器 -->
</mvc:async-support>
</mvc:annotation-driven>
</beans>

3、web.xml  , 当有 很多 filter 时,filter 也一定要添加异步支持

<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"> <filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<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>
</filter> <filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet> <servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

web.xml需要声明web-app_3_0.xsdversion=”3.0″,启用异步支持<async-supported>true</async-supported>
4、CallableController.java

package com.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView; import java.util.concurrent.Callable; /**
* spring实现方式:
* 1、把任务提交给Executor异步执行
*/
@Controller
public class CallableController { @RequestMapping(value = "/callable1", method = RequestMethod.GET)
public Callable<String> callable1(final ModelMap modelMap) {
return new Callable<String>() {
public String call() throws Exception {
Thread.sleep(2 * 1000L); //暂停2秒return "hello callable";
}
};
}
}

5,tomcat 部分,如果 tomcat 部署有 session  分页式缓存插件,则在插件配置的地方,也要添加异步支持:

    <!-- redis 缓存支持  --> 
<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" asyncSupported="true" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
host="localhost"
port="6379"
database="0"
maxInactiveInterval="60" />

6, 启动服务,测试:

http://localhost:8088/test/callable1


7, rsp:

hello callable

Spring MVC 异步测试的更多相关文章

  1. Spring mvc异步处理

    基于Servlet3.0的异步处理,springmvc的异步处理 控制器返回callable, spring mvc异步处理,将callable提交到TaskExecutor  使用一个隔离线程进行执 ...

  2. Spring MVC 异步处理请求,提高程序性能

    原文:http://blog.csdn.net/he90227/article/details/52262163 什么是异步模式 如何在Spring MVC中使用异步提高性能? 一个普通 Servle ...

  3. Spring MVC如何测试Controller(使用springmvc mock测试)

    在springmvc中一般的测试用例都是测试service层,今天我来演示下如何使用springmvc mock直接测试controller层代码. 1.什么是mock测试? mock测试就是在测试过 ...

  4. Spring MVC的测试

    测试是保证软件质量的关键. 与 Spring MVC 相关的测试,主要涉及控制器的测试. 为了测试Web项目通常不需要启动项目,需要一些Servlet相关的一些模拟对象,比如MockMVC.MockH ...

  5. spring mvc 异步 DeferredResult

    当一个请求到达API接口,如果该API接口的return返回值是DeferredResult,在没有超时或者DeferredResult对象设置setResult时,接口不会返回,但是Servlet容 ...

  6. Spring MVC 异步请求 Callable

    对于有的请求业务处理流程可能比较耗时,比如长查询,远程调用等,主线程会被一直占用,而tomcat线程池线程有限,处理量就会下降 servlet3.0以后提供了对异步处理的支持,springmvc封装了 ...

  7. spring mvc 和ajax异步交互完整实例

    Spring MVC 异步交互demo: 1.jsp页面: <%@ page language="java" contentType="text/html; cha ...

  8. spring3 jsp页面使用<form:form modelAttribute="xxxx" action="xxxx">报错,附连接数据库的spring MVC annotation 案例

    在写一个使用spring3 的form标签的例子时,一直报错,错误信息为:java.lang.IllegalStateException: Neither BindingResult nor plai ...

  9. Unit Testing of Spring MVC

    试验1:做的条目不发现首先,我们必须确保我们的应用是工作性质所做条目不发现.我们可以写的测试以确保通过以下步骤: 1.配置的模拟对象时抛出一个todonotfoundexception findbyi ...

随机推荐

  1. day77

    昨日回顾:  批量插入数据:   -queryset的方法:bulk_create(对象列表,数字(一次插入多少))  分页器:   from django.core.paginator import ...

  2. ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值

    用过ASP.NET Core MVC中IActionFilter拦截器的开发人员,都知道这是一个非常强大的MVC拦截器.最近才发现IActionFilter的OnActionExecuting方法,甚 ...

  3. 前后台分离式开发(swagger)

    一.前后台分离开发(swagger) 1.安装maven 配置的maven环境变量 M2_HOME/MAVEN_HOME Path %M2_HOME%/bin 打开运行窗口:输入mvn -v,查看是否 ...

  4. [笔记] Redis的安装与配置超级详细

    目录 Windows下安装与配置 下载 安装 验证安装 配置服务 测试 Linux下安装与配置 准备工作 安装 验证与测试 Macox下安装与配置 准备工作 安装 验证与测试 Redis 在 Wind ...

  5. net 表格控件

    一个开源的表格控件,界面像Excel,看来很好,有机会在项目中使用:ReoGrid https://reogrid.net/

  6. Python3入门(四)——Python函数

    一.概述 python和其他高级语言一样,支持函数 注意和scala不一样,结果必须使用return,否则默认return None!这和scala最后一个值作为返回是不一样的! 二.函数调用 和其他 ...

  7. 跟我学Android NDK开发(一)

    Android NDK 开发跟其它开发一样,首先需要配置好开发环境,本文以 Ubuntu系统为例介绍如何进行 Android NDK 开发环境的配置. 1. 简介 什么是 Android NDK 呢? ...

  8. 20155209林虹宇 Exp6 信息搜集与漏洞扫描

    Exp6 信息搜集与漏洞扫描 1.信息收集 1.1通过DNS和IP挖掘目标网站的信息 whois查询 进行whois查询时去掉www等前缀,因为注册域名时通常会注册一个上层域名,子域名由自身的域名服务 ...

  9. Centos 定时任务发送smtp邮件

    接着上一篇文章...... 1.首先创建一个sheel的脚本命令,我是在home文件夹下面创建的命令: touch a.sh 2.编辑a.sh脚本 vim a.sh ,键入键盘   i  键 准备插入 ...

  10. 总结 : C#事件理解

    要理解事件,首先必须理解委托!! 1.如果说委托是一个类型,那么事件就是一个对象! 2.事件的创建必须是借助某个委托类型来完成的! 3.也就是说,委托是事件的类型,事件本身是个对象!! 4.所以,事件 ...