转发地址:https://www.iteye.com/blog/wiselyman-2215852

9.1 异步请求处理

  • Servlet 3开始支持异步请求处理
  • Spring MVC 3.2开始支持Servlet3的这项特性
  • controller可以从另外一个线程返回一个java.util.concurrent.Callable,而不是一个简单的值
    • 此时Servlet容器线程已经释放,可以处理其他的请求
    • Spring MVC通过借助TaskExecutor调起另外一个线程(例子中的mvcTaskExecutor)
  • controller也可以从另外一个线程返回一个DeferredResult
    • 此时,Spring MVC并不知道这个线程的存在
    • 比如一个定时任务

9.2 演示

  • 05点睛Spring MVC 4.1-服务器端推送中,我们也演示了通过SSE实现长连接

    • 但在IE的一些版本是不支持的
  • 本例通过Spring MVC对异步处理的支持来演示长连接的支持,即服务器端推送

    • 支持所有浏览器
  • Servlet开启异步支持

package com.wisely;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; public class WebInitializer implements WebApplicationInitializer { @Override
public void onStartup(ServletContext servletContext)
throws ServletException {
AnnotationConfigWebApplicationContext ctx =
new AnnotationConfigWebApplicationContext();
ctx.register(DemoMVCConfig.class);
//注册spring mvc的DispatcherServlet
ctx.setServletContext(servletContext);
Dynamic servlet =
servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
servlet.setAsyncSupported(true);//此句开启 } }
  • DeferredResult所需的定时处理
package com.wisely.service;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult; @Service
public class AysncService {
private DeferredResult<String> deferredResult; public DeferredResult<String> getAsyncUpdate() {
deferredResult = new DeferredResult<String>();
return deferredResult;
} @Scheduled(fixedDelay = 5000)
public void refresh() {
if (deferredResult != null) {
deferredResult.setResult(new Long(System.currentTimeMillis())
.toString());
}
} }
  • 开启Spring MVC支持配置:继承WebMvcConfigurerAdapter的配置类DemoMVCConfig
  @Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(30*1000L); //tomcat默认10秒
configurer.setTaskExecutor(mvcTaskExecutor());//所借助的TaskExecutor
}
@Bean
public ThreadPoolTaskExecutor mvcTaskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setQueueCapacity(100);
executor.setMaxPoolSize(25);
return executor; } @Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/async").setViewName("/async");
}
  • 测试控制器
package com.wisely.web;

import java.util.concurrent.Callable;

import org.springframework.beans.factory.annotation.Autowired;
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; import com.wisely.service.AysncService; @Controller
public class AysncController { @Autowired
AysncService aysncService; @RequestMapping("/call")
@ResponseBody
public Callable<String> asyncCall() {
//借助mvcTaskExecutor在另外一个线程调用
//此时Servlet容器线程已经释放,可以处理其他的请求
return new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(3000);
return "Async Hello World";
}
};
} @RequestMapping("/defer")
@ResponseBody
public DeferredResult<String> deferredCall() {
//调用aysncService的getAsyncUpdate方法
//deferredResult被计划任务每五秒钟更新一次
return aysncService.getAsyncUpdate();
} }
  • 测试页面
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title> </head>
<body>
<input type="button" value="call" onclick="call();"/>
<input type="button" value="deferred" onclick="deferred();"/> <script type="text/javascript" src="<c:url value="/js/jquery.js" />"></script>
<script type="text/javascript"> function call(){
$.get('call',function(data){
console.log(data);
});
} function deferred(){
$.get('defer',function(data){
console.log(data);
deferred();//每次请求完成,再发一次请求,避免客户端定时刷新来获取数据
});
} </script>
</body>
</html>
  • 测试

    • 访问http://localhost:8080/testSpringMVC/async
    • 点击call

    • 点击defer

09点睛Spring MVC4.1-异步请求处理(包含兼容浏览器的服务器端推送)的更多相关文章

  1. 08点睛Spring MVC4.1-Spring MVC的配置(含自定义HttpMessageConverter)

    8.1 配置 Spring MVC的配置是通过继承WebMvcConfigurerAdapter类并重载其方法实现的; 前几个教程已做了得配置包括 01点睛Spring MVC 4.1-搭建环境 配置 ...

  2. 07点睛Spring MVC4.1-ContentNegotiatingViewResolver

    转发地址:https://www.iteye.com/blog/wiselyman-2214965 7.1 ContentNegotiatingViewResolver ContentNegotiat ...

  3. 10点睛Spring MVC4.1-全局异常处理

    10.1 全局异常处理 使用@ControllerAdvice注解来实现全局异常处理; 使用@ControllerAdvice的属性缩小处理范围 10.2 演示 演示控制器 package com.w ...

  4. Spring Web Async异步处理#Callable #DeferredResult

    Spring MVC 对于异步请求处理的两种方式 场景: Tomcat对于主线程性能瓶颈,当Tomcat请求并发数过多时,当线程数满时,就会出现请求等待Tomcat处理,这个时候可以使用子线程处理业务 ...

  5. 使用AJAX技术发送异步请求,HTTP服务端推送

    使用AJAX技术发送异步请求 什么是AJAX AJAX指一步Javascript和XML(Asynchronous JavaScript And XML),它是一些列技术的组合,简单来说AJAX基于X ...

  6. MVC异步消息推送机制

    在MVC里面,有异步控制器,可以实现模拟消息推送机制功能 1.控制器要继承至AsyncController,如 public class RealTimeController : AsyncContr ...

  7. Spring Mvc4 新特性(一)

    前言 Spring Framework的Web层,由spring-web,spring-webmvc,spring-websocket和spring-webmvc-portlet模块组成. 很多人刚学 ...

  8. 高性能的关键:Spring MVC的异步模式

    我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表的文章,以一个更简单的视角,把异步模式讲清楚. 什 ...

  9. Spring MVC的异步模式

    高性能的关键:Spring MVC的异步模式   我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表 ...

随机推荐

  1. fft相关的复习

    任意长度卷积 CZT 就是一波推导 \[ \begin{aligned} b_i &= \sum_{j=0}^{n-1} \omega^{ij}a_j \\ &= \sum_{j=0} ...

  2. BZOJ3551 Peaks加强版 [Kruskal重构树,主席树]

    BZOJ 思路 我觉得这题可持久化线段树合并也可以做 我觉得这题建出最小生成树之后动态点分治+线段树也可以做 还是学习一下Kruskal重构树吧-- Kruskal重构树,就是在做最小生成树的时候,如 ...

  3. 安装php的oracle扩展

    PHP 版本5.5 Windows下 1.首先下载OCI8的扩展 http://pecl.php.net/package/o... 我这里下的版本是5.5 Thread Safe (TS) x86 版 ...

  4. [洛谷 P4556] 雨天的尾巴

    传送门 Solution 线段树合并的入门题 lca可以在dfs的时候离线求(用并查集) 更新的点有每条链的两个端点,它们的lca和dad[lca] 为了节省空间,lca和dad[lca]的更新可以先 ...

  5. nginx代理mysql

    实验环境: 两台编译安装的mysql                            一台编译安装的nginx 192.168.3.1                               ...

  6. 扩展ACL

  7. MySQL5.7授权用户远程访问

    做个记录,每次弄环境的时候,特别是弄mysql环境,时不时都要用到下面的命令 命令如下: grant all privileges on *.* to 'root'@'%' identified by ...

  8. Mysql| 组合where子句过滤数据(AND,OR,IN,NOT)

    ysql 允许使用多个where子句,组合where子句允许使用两种方式使用:AND 和OR子句的方式使用.数据库中的操作符号:AND , OR , IN , NOT. AND:SELECT * FR ...

  9. idea创建类,接口,枚举等如何设置注释

    进入设置: File -> Settings   依次选择: Editor -> File and Code Templates -> Files -> Class (根据需要 ...

  10. To avoid slowing down lookups on a near-full table, we resize the table when it's USABLE_FRACTION (currently two-thirds) full.

    https://github.com/python/cpython/blob/3.8/Objects/dictobject.c