很久没有更新博客了,这段时间实在的忙的不可开交,项目马上就要上线了,要修补的东西太多了。当我在学习JavaWeb文件上传的时候,我就一直有一个疑问,网站上那些博客的图片是怎么上传的,因为当提交了表单之后网页就跳转了。后来我学习到了Ajax,我知道了浏览器可以异步的发送响应,这时我又有新的疑问,那就是在我上传一些文件的时候,那些网站的上传进度是怎么做到的,因为servlet直到上传完成之后才完成响应。

最近我们的项目中有一个地方中需要用到一个功能,当用户点击一个处理按钮时,前台会实时的显示后台处理动态,由于servlet一次只能接受一个请求,而且在servlet的生命周期结束时才会把响应数据发送到前台(这一点大家可以做个这样的测试:
response.getWriter().print("hello");
Thread.sleep(10000);
response.getWriter().print("world");
你们会发现前台在等待了约10s后收到了"helloworld")。所以我想到了一个方法:使用单例保存实时信息。具体的实现方法就是,当用户点击了处理按钮时,在后台开启一个线程进行处理,并且每进行到一步,就向单例中写入当前状态信息。然后编写一个servlet,用于返回单例中的信息,前台循环发送请求,这样就能实现实时显示进度的效果。
好了,啰嗦了这么多,下面进入正题,如何实现上传文件动态显示进度,其实思想和上面的功能是一致的,我将这个功能分为三个点:
1.单例:用于保存进度信息;
2.上传servlet:用于上传文件并实时写入进度;
3.进度servlet:用于读取实时进度信息;
上代码,前台:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
#progress:after {
content: '%';
}
</style>
</head>
<body>
<h3>File upload demo</h3>
<form action="TestServlet" method="post" enctype="multipart/form-data" id="dataForm">
<input type="file" name="file" id="fileInput"> <br>
<input type="submit" value="submit" id="submit">
</form>
<div id="progress"></div>
<script type="text/javascript" src="scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
(function () {
var form = document.getElementById("dataForm");
var progress = document.getElementById("progress");
$("#submit").click(function(event) {
//阻止默认事件
event.preventDefault();
//循环查看状态
var t = setInterval(function(){
$.ajax({
url: 'ProgressServlet',
type: 'POST',
dataType: 'text',
data: {
filename: fileInput.files[0].name,
},
success: function (responseText) {
var data = JSON.parse(responseText);
//前台更新进度
progress.innerText = parseInt((data.progress / data.size) * 100);
},
error: function(){
console.log("error");
}
});
}, 500);
//上传文件
$.ajax({
url: 'UploadServlet',
type: 'POST',
dataType: 'text',
data: new FormData(form),
processData: false,
contentType: false,
success: function (responseText) {
//上传完成,清除循环事件
clearInterval(t);
//将进度更新至100%
progress.innerText = 100;
},
error: function(){
console.log("error");
}
});
return false;
});
})();
</script>
</body>
</html>
后台,单例:
import java.util.Hashtable;
public class ProgressSingleton {
//为了防止多用户并发,使用线程安全的Hashtable
private static Hashtable<Object, Object> table = new Hashtable<>();
public static void put(Object key, Object value){
table.put(key, value);
}
public static Object get(Object key){
return table.get(key);
}
public static Object remove(Object key){
return table.remove(key);
}
}
上传servlet:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
import singleton.ProgressSingleton;
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public UploadServlet() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(4*1024);
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> fileItems;
try {
fileItems = upload.parseRequest(new ServletRequestContext(request));
//获取文件域
FileItem fileItem = fileItems.get(0);
//使用sessionid + 文件名生成文件号
String id = request.getSession().getId() + fileItem.getName();
//向单例哈希表写入文件长度和初始进度
ProgressSingleton.put(id + "Size", fileItem.getSize());
//文件进度长度
long progress = 0;
//用流的方式读取文件,以便可以实时的获取进度
InputStream in = fileItem.getInputStream();
File file = new File("D:/test");
file.createNewFile();
FileOutputStream out = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int readNumber = 0;
while((readNumber = in.read(buffer)) != -1){
//每读取一次,更新一次进度大小
progress = progress + readNumber;
//向单例哈希表写入进度
ProgressSingleton.put(id + "Progress", progress);
out.write(buffer);
}
//当文件上传完成之后,从单例中移除此次上传的状态信息
ProgressSingleton.remove(id + "Size");
ProgressSingleton.remove(id + "Progress");
in.close();
out.close();
} catch (FileUploadException e) {
e.printStackTrace();
}
response.getWriter().print("done");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
进度servlet:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import singleton.ProgressSingleton;
@WebServlet("/ProgressServlet")
public class ProgressServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ProgressServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getSession().getId();
String filename = request.getParameter("filename");
//使用sessionid + 文件名生成文件号,与上传的文件保持一致
id = id + filename;
Object size = ProgressSingleton.get(id + "Size");
size = size == null ? 100 : size;
Object progress = ProgressSingleton.get(id + "Progress");
progress = progress == null ? 0 : progress;
JSONObject json = new JSONObject();
json.put("size", size);
json.put("progress", progress);
response.getWriter().print(json.toString());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# java实现上传进度条
# java上传文件带进度条
# java文件上传进度条
# java 教你如何给你的头像添加一个好看的国旗
# Java Struts图片上传至指定文件夹并显示图片功能
# Java Servlet上传图片到指定文件夹并显示图片
# Java动态显示文件上传进度实现代码
# Java web实现头像上传以及读取显示
# 上传
# 上传文件
# 是怎么
# 文件上传
# 我想
# 我就
# 在我
# 好了
# 就能
# 这么多
# 中有
# 又有
# 当我
# 这段
# 博客
# 做个
# 我将
# 跳转
# 发送到
# 会把
相关文章:
娃派WAP自助建站:免费模板+移动优化,快速打造专业网站
网站制作报价单模板图片,小松挖机官方网站报价?
javascript中对象的定义、使用以及对象和原型链操作小结
定制建站如何定义?其核心优势是什么?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
建站之星如何开启自定义404页面避免用户流失?
建站之星在线版空间:自助建站+智能模板一键生成方案
如何通过cPanel快速搭建网站?
如何用虚拟主机快速搭建网站?详细步骤解析
定制建站平台哪家好?企业官网搭建与快速建站方案推荐
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
如何通过服务器快速搭建网站?完整步骤解析
网站网页制作专业公司,怎样制作自己的网页?
股票网站制作软件,网上股票怎么开户?
单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?
如何选择服务器才能高效搭建专属网站?
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
C++如何将C风格字符串(char*)转换为std::string?(代码示例)
网站制作说明怎么写,简述网页设计的流程并说明原因?
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
北京的网站制作公司有哪些,哪个视频网站最好?
如何通过宝塔面板实现本地网站访问?
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
深圳 网站制作,深圳招聘网站哪个比较好一点啊?
油猴 教程,油猴搜脚本为什么会网页无法显示?
建站主机选购指南与交易推荐:核心配置解析
建站之星会员如何解锁更多建站功能?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
企业网站制作公司网页,推荐几家专业的天津网站制作公司?
清除minerd进程的简单方法
香港服务器网站卡顿?如何解决网络延迟与负载问题?
专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
昆明网站制作哪家好,昆明公租房申请网上登录入口?
建站上市公司网站建设方案与SEO优化服务定制指南
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
微信网站制作公司有哪些,民生银行办理公司开户怎么在微信网页上查询进度?
佛山网站制作系统,佛山企业变更地址网上办理步骤?
小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
,如何利用word制作宣传手册?
专业网站设计制作公司,如何制作一个企业网站,建设网站的基本步骤有哪些?
定制建站流程解析:需求评估与SEO优化功能开发指南
网站企业制作流程,用什么语言做企业网站比较好?
如何在搬瓦工VPS快速搭建网站?
简历在线制作网站免费,免费下载个人简历的网站是哪些?
建设网站制作价格,怎样建立自己的公司网站?
深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的?
*请认真填写需求信息,我们会在24小时内与您取得联系。