转发地址: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. js文件夹上传下载组件

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  2. learning java AWT Dialog

    import java.awt.*; public class DialogTest { Frame f = new Frame("test"); Dialog d1 = new ...

  3. 洛谷 4290 [HAOI2008]玩具取名 题解

    P4290 [HAOI2008]玩具取名 题目描述 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用&qu ...

  4. typescript 错误记录

    经常遇到 typescript 的编译错误,虽然可以绕过去,不过既然采用了,还是解决问题,了解其中的思想比较重要. 一般遇到错误码 error TS2304: Cannot find name ... ...

  5. golang-结构体的使用

    package main import ( "fmt" "unsafe" ) type Person struct { name string sex byte ...

  6. java学习笔记(3)数据类型、源码、反码、补码、精度损失、基本数据类型互相转换

    关于java中的数据类型: 1.数据类型的作用是什么? 程序当中有很多数据,每一个数据都是有相关类型的,不同数据类型的数据占用的空间大小不同. 数据类型的作用是指导java虚拟机(JVM)在运行程序的 ...

  7. P2016 战略游戏——树形DP大水题

    P2016 战略游戏 树形DP 入门题吧(现在怎么是蓝色标签搞不懂): 注意是看见每一条边而不是每一个点(因为这里错了好几次): #include<cstdio> #include< ...

  8. Leetcode84. 柱状图中最大的矩形(单调栈)

    84. 柱状图中最大的矩形 前置 单调栈 做法 连续区间组成的矩形,是看最短的那一块,求出每一块左边第一个小于其高度的位置,右边也同理,此块作为最短限制.需要两次单调栈 单调栈维护递增区间,每次不满足 ...

  9. docker中部署django项目~~Dockfile方式和compose方式

    1.  背景:   本机win10上,后端django框架代码与前端vue框架代码联调通过. 2.  目的:   在centos7系统服务器上使用docker容器部署该项目. 3.  方案一:仅使用基 ...

  10. 【Vue.js游戏机实战】- Vue.js实现九宫格水果机抽奖游戏总结

    大家好!先上图看看本次案例的整体效果. 完整版实战课程附源码:[Vue.js游戏机实战]- Vue.js实现九宫格水果机抽奖 实现思路: Vue component实现九宫格水果机组件,可以嵌套到任意 ...