Servlet 3.0+ 异步方法实现服务端消息推送是通过使用定时任务,定时的让控制器从另外一个线程返回一个DeferedResult
并推送给客户端。而更新DeferedResult
是在使用@Scheduled
定时任务注解的方法里执行的。
示例
Maven管理的项目,pom.xml
添加Servlet 3.0+
版本依赖包。
- 在
SpringMvcConfig.java
类上添加开启定时任务的注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Configuration @EnableWebMvc @EnableScheduling @ComponentScan(basePackages = {"com"}) public class SpringMvcConfig extends WebMvcConfigurerAdapter {
@Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp"); viewResolver.setViewClass(JstlView.class); return viewResolver; }
|
- Web初始化类时添加开启Servlet3.0+异步方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public class WebInitializer implements WebApplicationInitializer {
@Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(SpringMvcConfig.class); context.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context)); servlet.addMapping("/"); servlet.setLoadOnStartup(1); servlet.setAsyncSupported(true); } }
|
- Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Controller public class AysncController {
@Autowired PushServiceImpl pushServiceImpl; @RequestMapping("/async") public String asyncPage() { return "async"; }
@RequestMapping("/defer") @ResponseBody public DeferredResult<String> deferredCall() { return pushServiceImpl.getAsyncUpdate(); } }
|
- Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Service public class PushServiceImpl { private DeferredResult<String> deferredResult; public DeferredResult<String> getAsyncUpdate(){ deferredResult = new DeferredResult<>(); return deferredResult; } @Scheduled(fixedDelay = 5000) public void refresh() { if(deferredResult != null) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateTime = sdf.format(System.currentTimeMillis()); deferredResult.setResult("NowDateTime: " + dateTime); } } }
|
- jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!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">
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.11.0.js"></script>
<script type="text/javascript"> var s = ''; deferred(); function deferred() { $.get('defer', function(data) { console.log(data); s = s + (data + "<br/>"); $("#msgFromPush").html(s); deferred(); }) } </script>
<title>SSE Demo</title> </head> <body> <div id="msgFromPush"></div> </body> </html>
|
参考资料
Servlet 3特性:异步Servlet
tomcat servlet3的异步化原理理解