10.Spring MVC4.1-异步请求处理(包含兼容浏览器的服务器端推送)

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

10.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

   

springmvc 处理异步请求

springmvc 3.2开始就支持servlet3.0的异步请求。平常我们请求一个controller一般都是同步的,如果在代码执行中,遇到耗时的业务操作,那servlet容器线程就会被锁死,当有其...
  • yingxiake
  • yingxiake
  • 2016年04月19日 20:26
  • 9136

理解Spring MVC中的异步处理请求(下)

本文主要在上一篇文章的基础上进一步深入介绍了Spring MVC的另一种异步处理请求的方式,已经如何提供服务器推送服务。...
  • gg_18826075157
  • gg_18826075157
  • 2017年06月01日 22:51
  • 1284

Servlet3-异步请求-DeferredResult

第22章 异步请求 Servlet3.0规范新增了对异步请求的支持,spring MVC也在此基础上对异步请求提供了方便。异步请求是在处理比较耗时的业务时先将request返回,然后另起线程处理...
  • tanqian351
  • tanqian351
  • 2017年07月31日 16:24
  • 205

7、Spring MVC 之 处理异步请求

Spring MVC 3.2开始引入Servlet 3中的基于异步的处理request.往常是返回一个值,而现在是一个Controller方法可以返回一个java.util.concurrent.Ca...
  • u012410733
  • u012410733
  • 2016年08月04日 23:29
  • 11060

spring 3以及之后版本的异步方法

这里我们来看看spring 3.0 以及以后版本中支持的@Async (方法异步) 其实在之前的程序中也没看到过有使用@Async 的,最近才接触到,想着如果使用异步缓存是不是响应速度会大幅提升那,就...
  • QH_JAVA
  • QH_JAVA
  • 2016年07月14日 09:19
  • 5680

长轮询 Servlet实现

长轮询@RequestMapping("/ajax") public void ajax(long timed, HttpServletResponse response) throws Except...
  • qq_17612199
  • qq_17612199
  • 2016年10月11日 16:19
  • 929

6. Spring MVC 4.1-服务器端推送

6.1 服务器端推送 SSE(server send event)是一种服务器端向浏览器推送消息的技术,而不是我们常规的浏览器像server请求然后响应;当我们需要使...
  • software444
  • software444
  • 2015年11月19日 21:44
  • 3308

SpringMVC整合websocket实现消息推送及触发

1.创建websocket握手协议的后台 (1)HandShake的实现类 /** *Project Name: price *File Name: HandShake.java *Pac...
  • liuyunshengsir
  • liuyunshengsir
  • 2016年09月10日 17:20
  • 13438

spring+websocket整合(springMVC+spring+MyBatis即SSM框架和websocket技术的整合)

纠结了两天的
  • UP19910522
  • UP19910522
  • 2014年08月06日 00:30
  • 99080

Java+Spring长连接实现后台主动发送数据给前端

1.什么是长连接、短连接?在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的...
  • JacXuan
  • JacXuan
  • 2018年01月09日 10:12
  • 324
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:10.Spring MVC4.1-异步请求处理(包含兼容浏览器的服务器端推送)
举报原因:
原因补充:

(最多只允许输入30个字)