很久没有更新博客了,这段时间实在的忙的不可开交,项目马上就要上线了,要修补的东西太多了。当我在学习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实现头像上传以及读取显示
# 上传
# 上传文件
# 是怎么
# 文件上传
# 我想
# 我就
# 在我
# 好了
# 就能
# 这么多
# 中有
# 又有
# 当我
# 这段
# 博客
# 做个
# 我将
# 跳转
# 发送到
# 会把
相关文章:
七夕网站制作视频,七夕大促活动怎么报名?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
如何零基础开发自助建站系统?完整教程解析
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
如何选择高效稳定的ISP建站解决方案?
制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?
广东企业建站网站优化与SEO营销核心策略指南
利用JavaScript实现拖拽改变元素大小
建站DNS解析失败?如何正确配置域名服务器?
如何在VPS电脑上快速搭建网站?
制作营销网站公司,淘特是干什么用的?
网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?
临沂网站制作企业,临沂第三中学官方网站?
文字头像制作网站推荐软件,醒图能自动配文字吗?
Swift中switch语句区间和元组模式匹配
西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?
哈尔滨网站建设策划,哈尔滨电工证查询网站?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】
h5网站制作工具有哪些,h5页面制作工具有哪些?
如何通过西部数码建站助手快速创建专业网站?
小型网站建站如何选择虚拟主机?
Android滚轮选择时间控件使用详解
网站制作网站,深圳做网站哪家比较好?
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
山东云建站价格为何差异显著?
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
如何在景安服务器上快速搭建个人网站?
网站制作费用多少钱,一个网站的运营,需要哪些费用?
为什么Go需要go mod文件_Go go mod文件作用说明
公众号网站制作网页,微信公众号怎么制作?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
c# 服务器GC和工作站GC的区别和设置
如何通过宝塔面板实现本地网站访问?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
已有域名和空间如何搭建网站?
宝塔新建站点为何无法访问?如何排查?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
建站之星云端配置指南:模板选择与SEO优化一键生成
兔展官网 在线制作,怎样制作微信请帖?
h5在线制作网站电脑版下载,h5网页制作软件?
学校建站服务器如何选型才能满足性能需求?
如何在云主机上快速搭建多站点网站?
如何在阿里云购买域名并搭建网站?
开心动漫网站制作软件下载,十分开心动画为何停播?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
高防服务器租用如何选择配置与防御等级?
如何快速上传建站程序避免常见错误?
*请认真填写需求信息,我们会在24小时内与您取得联系。