注:源代码来自享学课堂,略有修改,学习之后所做笔记,方便回顾,也给大家一个参考
DeferredResult实现长轮询
页面每次调用请求之后,在方法结束的时候,再次自我调用
<%@ 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>测试</title>
</head>
<body>
<h1>新闻</h1>
<div>
<div>
<h2实时变化的新闻</h2>
<div style="color:#F00"><b><p id="realTimeNews"> </p></b></div>
</div>
</div>
<script type="text/javascript" src="assets/js/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
longLoop();
function longLoop() {
$.get("realTimeNews",function (data) {
console.log(data);
$("#realTimeNews").html(data);
//马上再发起请求
longLoop();
})
}
</script>
</body>
</html>
服务器要开启异步调用, servlet.setAsyncSupported(true);这里的WebApplicationInitializer相当于web.xml配置修改
public class WebInit implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
AnnotationConfigWebApplicationContext ctx
= new AnnotationConfigWebApplicationContext();
ctx.register(CometMvcConfig.class);
ctx.setServletContext(servletContext);
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher",
new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
//启用异步
servlet.setAsyncSupported(true);
}
}
服务器基本配置
@Configuration
@EnableWebMvc
@EnableScheduling
@ComponentScan("cn.gg")
public class CometMvcConfig extends WebMvcConfigurerAdapter{
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**")
.addResourceLocations("/assets/");
}
}
生成任意消息的对象
public class Const {
public static final String[] NEWS = {
"床前明月光",
"疑是地上霜",
"举头望明月",
"低头思故乡"
};
}
使用DeferredResult实现长轮询
@Controller
@RequestMapping(produces="text/html;charset=UTF-8")
/*记得要在WebInitializer中增加servlet.setAsyncSupported(true);*/
public class PushNewsController {
private ExecutorService executorService
= Executors.newFixedThreadPool(1);
@RequestMapping("/pushnews")
public String news(){
return "pushNews";
}
@RequestMapping(value="/realTimeNews")
@ResponseBody
/*在WebInitializer中要加上servlet.setAsyncSupported(true);*/
public DeferredResult<String> realtimeNews(HttpServletRequest request){
final DeferredResult<String> dr = new DeferredResult<String>();
executorService.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int index = new Random().nextInt(Const.NEWS.length);
//setResult会刷新页面的数据
dr.setResult(Const.NEWS[index]);
}
});
return dr;
}
}
访问页面的时候,新闻会不断自动刷新