从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. 串口通信DMA中断

    这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影.关于dma网上有许多的资料,亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但是自己本身打字就慢,还有好多事情 ...

  2. day63

    一.环境搭建 1.安装node 去官网下载node安装包 傻瓜式安装 万一安装后终端没有node环境,要进行node环境变量的配置(C:\Program Files\nodejs) 可以通过node提 ...

  3. day57

    JQ初级 一.认识jQuery 1.什么是jQuery jQuery是对原生JavaScript二次封装的工具函数集合 jQuery是一个简洁高效的且功能丰富的JavaScript工具库 2.jQue ...

  4. golang 文件服务器

    在go语言中可以用一句代码做一个文件服务器.如果有很多文件需要通过网页来供其他人下载,可以使用这个方法. package main import ( "log" "net ...

  5. 《Head First 设计模式》[01] 策略模式

    <Head First 设计模式>(点击查看详情) 1.写在前面的话 之前在列书单的时候,看网友对于设计模式的推荐里说,设计模式的书类别都大同小异,于是自己就选择了Head First系列 ...

  6. Net Core 使用外部登陆提供程序登陆的流程,以及身份认证的流程

    在Asp.Net Core 中使用外部登陆(google.微博...)   原文出自Rui Figueiredo的博文<External Login Providers in ASP.NET C ...

  7. vi学习

    刚开始学习vi,所以,一步一步开始 先贴出一个相关的学习链接https://www.cnblogs.com/ranjiewen/p/5901181.html 这个学习链接里面的东西还是比较详细的,但是 ...

  8. 20155236范晨歌_Web基础

    20155236范晨歌_Web基础 目录 实践目标 Apache 前端编程 后端编程 PHP MYSQL & 后端 简单SQL注入与XSS 发帖和会话管理 实践目标 (1)Web前端HTML ...

  9. 20155323刘威良《网络对抗》Exp5 MSF基础应用

    20155323刘威良<网络对抗>Exp5 MSF基础应用 实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 1.1一个主动攻击实 ...

  10. C# DataGridView控件禁止拷贝数据

    代码如下(没错,就一行): dataGridView1.ClipboardCopyMode=DataGridViewClipboardCopyMode.Disable; 当然其它方式很多,但是不如来个 ...