jsp实时显示后台批处理进度 - out分块,简单的长连接方式
这两天在实现一个批处理操作,但是想让前台实时显示后台批处理进度,本想着用复杂一些的框架可以实现异步信息调用
但是鉴于是内部管理系统,且只有一两个人用到这个功能,所以做了一个简单的长连接方式的实时响应
有些人说使用ajax请求,定时刷新,个人觉得很耗服务器资源,而且准确的说也不是实时的
【原文摘自 BearRui(AK-47) 的Blog】http://www.blogjava.net/BearRui/archive/2010/06/01/ajax_better_experience.html
使用技术:AJAX - onreadystatechange 事件
详细解释:http://www.runoob.com/ajax/ajax-xmlhttprequest-onreadystatechange.html
MSDN:https://msdn.microsoft.com/en-us/library/ms535874(VS.85).aspx
要解决实现上面的功能,需要解决下面几个问题:
1. 服务器如何在处理一部分数据后传递部分response到浏览器。
2、浏览器如何能处理服务器传递过来部分数据,并保持http连接直到处理完全完毕。
解决
第1个问题,使用flush让response分块进行呈现就可以了,具体请参考我另一遍随笔"flush让页面分块,逐步呈现 http://www.blogjava.net/BearRui/archive/2010/05/19/flush_chunk_encoding.html";
第2个问题,则需要用到XMLHttpRequest的readyState状态,w3c对 readyState 定义如下几个值:
UNSENT = 0; // 没有发送请求
OPENED = 1; // 已经打开http连接
HEADERS_RECEIVED = 2; // 接收到response header
LOADING = 3; // 真正接收response body
DONE = 4; // 请求接收完毕
另外的问题: readyState每次返回0-4的状态时,state的值是多少呢?200吗?还是其他?
首先,status是XMLHttpRequest对象的一个属性,表示响应的HTTP状态码。
在HTTP1.1协议下,HTTP状态码总共可分为5大类,如下表所示:
1XX 服务器收到请求,需要继续处理。例如101状态码,表示服务器将通知客户端使用更高版本的HTTP协议。
2XX 请求成功。例如200状态码,表示请求所希望的响应头或数据体将随此响应返回。
3XX 重定向。例如302状态码,表示临时重定向,请求将包含一个新的URL地址,客户端将对新的地址进行GET请求。
4XX 客户端错误。例如404状态码,表示客户端请求的资源不存在。
5XX 服务器错误。例如500状态码,表示服务器遇到了一个未曾预料的情况,导致了它无法完成响应,一般来说,这个问题会在程序代码出错时出现。
其次,经过测试,每次readyState有状态变化,如果后台不异常,那么返回都是200,所以当readyState返回4时候,需要对state=200做判断,否则提示批处理异常
下面来看代码
- ===================前端代码====================
- //打开框
- $('#settle-batch').dialog("center");
- settleBatch.html("");
- $('#settle-batch').dialog('open').dialog('setTitle', "批量处理进度显示");
- //发送批处理请求
- var xhr = new window.XMLHttpRequest();
- if(!window.XMLHttpRequest){
- try {
- xhr = new window.ActiveXObject("Microsoft.XMLHTTP");
- } catch(e) {
- alertMsg("失败", "创建请求失败,请重试");
- }
- }
- xhr.open("post","http://localhost:8081/WMS/agentsettle/batch");
- settleBatch.append("<p>正在发送批处理请求 ...</p>");
- //处理实时回调信息
- var oldSize=0;
- xhr.onreadystatechange = function(){
- var readyState = xhr.readyState;
- //成功发送请求
- if(readyState == 2){
- settleBatch.append("<p>启动上月代理分成批处理</p>");
- settleBatch.append("<p style='margin: 10px;'></p>");
- }
- //接收事实数据
- if(readyState > 2){
- var tmpText = xhr.responseText.substring(oldSize);
- oldSize = xhr.responseText.length;
- if(tmpText.length > 0 ){
- // 设置文本
- var str = tmpText.replace(/"/g, "");
- settleBatch.append("<p>" + str + "</p>");
- }
- }
- //处理成功
- if(readyState == 4){
- settleBatch.append("<p style='margin: 10px;'></p>");
- if (xhr.status === 200) {
- settleBatch.append("<p>批处理完成 !!!</p>");
- } else {
- settleBatch.append("<p>批处理异常结束 !!!???</p>");
- }
- }
- }
- xhr.send(null);
- =============后台代码==================
- response.setHeader("Content-Type","application/x-javascript");
- //设置out的字符编码,否则到前台可能中文乱码
- response.setCharacterEncoding("UTF-8");
- PrintWriter out = getResponse().getWriter();
- Thread.sleep(1000);
- out.println("正在处理第1个 ...");
- out.flush();
- Thread.sleep(1000);
- out.println("正在处理第2个 ...");
- out.flush();
- Thread.sleep(1000);
- out.println("正在处理第3个 ...");
- out.flush();
- Thread.sleep(1000);
- out.println("正在处理第4个 ...");
经测试,现在chrome、firefox、360浏览器都支持readyState=3的处理
基于Webkit的浏览器支持的不是很好,需要设置Content-Type:application/x-javascript才行(经测试发现Content-Type:text/html在有些情况下正常,有些情况下又不正常,而用application/x-javascript都正常)。
另外方法:
1、jquery 1.5已经支持onreadysatechange,可以使用
2、有些 消息异步通讯 的框架也可以实现这样的功能,不过要看实现实时显示的功能复杂度
jsp实时显示后台批处理进度 - out分块,简单的长连接方式的更多相关文章
- Asp.Net MVC页面显示后台处理进度问题
这个问题的背景是,用户通过浏览器上传文件或Excel数据到系统中,页面需要时时显示后台处理进度,以增强用户的体验. 在GitHub上找到一个一个项目,基本实现了这个功能,具体效果如下图 代码实现过程大 ...
- [Swift通天遁地]四、网络和线程-(9)上传图片并实时显示上传进度
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Javaweb项目页面实时显示后台处理结果
http://www.cnblogs.com/dong-xu/p/6701271.html 此博文甚好,项目参照博主代码可实现. 前端页面: <%@ page language="ja ...
- ASP.NET CORE使用WebUploader对大文件分片上传,并通过ASP.NET CORE SignalR实时反馈后台处理进度给前端展示
本次,我们来实现一个单个大文件上传,并且把后台对上传文件的处理进度通过ASP.NET CORE SignalR反馈给前端展示,比如上传一个大的zip压缩包文件,后台进行解压缩,并且对压缩包中的文件进行 ...
- 使用Uploadify实现上传图片生成缩略图例子,实时显示进度条
不了解Uploadify的,先看看前一篇详细说明 http://www.cnblogs.com/XuebinDing/archive/2012/04/26/2470995.html Uploadify ...
- 基于Jquery插件Uploadify实现实时显示进度条上传图片
网址:http://www.jb51.net/article/83811.htm 这篇文章主要介绍了基于Jquery插件Uploadify实现实时显示进度条上传图片的相关资料,感兴趣的小伙伴们 ...
- [Swift通天遁地]四、网络和线程-(8)下载图片并实时显示下载进度
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- C#调PowerShell在SCVMM中创建虚拟机时,实时显示创建进度
关于c#调用PowerShell来控制SCVMM,网上有很多例子,也比较简单,但创建虚拟机的过程,是一个很漫长的时间,所以一般来说,创建的时候都希望可以实时的显示当前虚拟机的创建进度.当时这个问题困扰 ...
- Web页面实现后台数据处理进度与剩余时间的显示
1.页面后台代码添加如下属性: /// <summary> /// 总数 /// </summary> private double total { set { Session ...
随机推荐
- Hibernate jar包详解
Hibernate一共包括了23个jar包,令人眼花缭乱.本文将详细讲解Hibernate每个jar包的作用,便于你在应用中根据自己的需要进行取舍. 下载Hibernate,例如2.0.3稳定版本,解 ...
- hdu1024 Max Sum Plus Plus
动态规划,给定长度为n(≤1e6)的整数数组和整数m,选取m个连续且两两无交集的子区间,求所有方案中使得区间和最大的最大值. dp[i][j]表示结束位置(最后一个区间最后一个元素的位置)为i且选取区 ...
- 单链表操作B 分类: 链表 2015-06-07 12:42 15人阅读 评论(0) 收藏
数据结构上机测试2-2:单链表操作B TimeLimit: 1000ms Memory limit: 65536K 题目描述 按照数据输入的相反顺序(逆位序)建立一个单链表,并将单链表中重复的元素删除 ...
- Poj(1220),hash
题目链接:http://poj.org/problem?id=1200 这个题,我真是无限MLE,RE,WA,太伤心了,还是写一下吧.题意很简单(英语很好读),最后看了一下金海峰的思路.果然,应该是我 ...
- nautilus-open-terminal很有用的插件--鼠标右键打开终端
1.1fedora安装# yum -y install nautilus-open-terminal安装nautilus-open-terminal,注销下X桌面即可ubuntu安装#sudo apt ...
- HDU 4810 Wall Painting
Wall Painting Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- linux 强大的编辑器之vi
vi编辑器是一个处理ASCII数据的文本工具.大多数linux发行版都已经默认安装了vi编辑器.vi是visual interface的缩写vim是 visual interface improved ...
- (1)创建一个叫做People的类: 属性:姓名、年龄、性别、身高 行为:说话、计算加法、改名 编写能为所有属性赋值的构造方法; (2)创建主类: 创建一个对象:名叫“张三”,性别“男”,年龄18岁,身高1.80; 让该对象调用成员方法: 说出“你好!” 计算23+45的值 将名字改为“李四”
package a; public class People { private String name,sex; private int age; private double height; pu ...
- DbUtils使用时抛出Cannot get a connection
java.sql.SQLException: Cannot get a connection, pool error Timeout waiting for idle object Caused by ...
- SQL触发器,数据库
触发器类型有两种: 1.AFTER(FOR)触发器 在动作执行之后触发(增删改执行完成后,触发器中的代码再执行),不能为视图指定for触发器,只能为表指定该触发器. 2.instead of触发器 可 ...