方法:使用单例保存实时信息。具体的实现方法就是,当用户点击了处理按钮时,在后台开启一个线程进行处理,并且每进行到一步,就向单例中写入当前状态信息。然后编写一个servlet,用于返回单例中的信息,前台循环发送请求,这样就能实现实时显示进度的效果。、
1,建立一个单例保存信息
2.上传servlet
3.进度 servlet
1.1以下为前端代码
标题文件上传DEMO
以下为前端显示部分
文件上传:
登录:
以下为具体实施过程 主要是ajax导入相关的jquery包
20
21 (function () {
22 var form = document.getElementById("dataForm");
23 var progress = document.getElementById("progress");
24
25 $("#submit").click(function(event) {
26 //阻止默认事件
27 event.preventDefault();
28 //循环查看状态
setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。一每次--**秒的时间进行循环
29 var t = setInterval(function(){
30 $.ajax({
31 url: 'ProgressServlet',
32 type: 'POST',
33 dataType: 'text',
34 data: {
35 filename:fileInput.files[0].name,
36 },
37 success: function(responseText) {
38 var data =JSON.parse(responseText);
39 //前台更新进度
40 progress.innerText =parseInt((data.progress / data.size) * 100);
41 },
42 error: function(){
43 console.log("error");
44 }
45 });
46 }, 时间);
47 //上传文件
48 $.ajax({
49 url: 'UploadServlet',
50 type: 'POST',
51 dataType: 'text',
52 data: new FormData(form),
53 processData: false,
54 contentType: false,
55 success: function(responseText) {
56 //上传完成,清除循环事件. clearInterval是关闭setInterval设置的时间
57 clearInterval(t);
58 //将进度更新至100%
59 progress.innerText = 100;
60 },
61 error: function(){
62 console.log("error");
63 }
64 });
65 return false;
66 });
67 })();
68
2.1一个类实现单例进行存储
import java.util.Hashtable;
3 publicclass ProgressSingleton {
4 //为了防止多用户并发,使用线程安全的Hashtable
5 private static Hashtable table = new Hashtable<>();
6
7 public static void put(Object key, Objectvalue){
8 table.put(key, value);
9 }
10
11 public static Object get(Object key){
12 return table.get(key);
13 }
14
15 public static Object remove(Object key){
16 return table.remove(key);
17 }
18 }
3.1上传类
@WebServlet("/UploadServlet")
22 public class UploadServlet extendsHttpServlet {
23 private static final long serialVersionUID = 1L;
24
25 public UploadServlet() {
26 }
27
28 protected void doGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {
29 DiskFileItemFactory接口是进行存储上传文件,当文件较小是直接存储在内存中,但是jvm是有限的,因此如果文件比较大时,存在缓存盘里面DiskFileItemFactory是创建FileItem对象的工厂包括方法:
30 DiskFileItemFactory factory = new DiskFileItemFactory();
setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值(以字节为单位的int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。对应的getSizeThreshold() 方法用来获取此临界值。
31 factory.setSizeThreshold(4*1024);
32 ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成
一个FileItem对象中.
33 ServletFileUpload upload = new ServletFileUpload(factory);
34 DiskFileItem类是它的实现FileItem
35 List fileItems;文件下载
36 try {
parseRequest 解析出http中表单的数据 然后将他们分别包装成FileItem对象,然后将这些存到集合里返回
37 fileItems = upload.parseRequest(newServletRequestContext(request));
38 //获取文件域
39 FileItem fileItem =fileItems.get(0);有问题
40 //使用sessionid+ 文件名生成文件号
41 String id =request.getSession().getId() + fileItem.getName();
42 //向单例哈希表写入文件长度和初始进度
43 ProgressSingleton.put(id +"Size", fileItem.getSize());
44 //文件进度长度
45 long progress = 0;
46 //用流的方式读取文件,以便可以实时的获取进度
47 InputStream in =fileItem.getInputStream();
48 File file = newFile("D:/test");
49 file.createNewFile();
50 FileOutputStream out = newFileOutputStream(file);
51 byte[] buffer = new byte[1024];
52 int readNumber = 0;
53 while((readNumber =in.read(buffer)) != -1){
54 //每读取一次,更新一次进度大小
55 progress = progress +readNumber;
56 //向单例哈希表写入进度
57 ProgressSingleton.put(id +"Progress", progress);
58 out.write(buffer);
59 }
60 //当文件上传完成之后,从单例中移除此次上传的状态信息
61 ProgressSingleton.remove(id +"Size");
62 ProgressSingleton.remove(id +"Progress");
63 in.close();
64 out.close();
65 } catch (FileUploadException e) {
66 e.printStackTrace();
67 }
68
69 response.getWriter().print("done");
70 }
71
72 protected void doPost(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {
73 doGet(request, response);
74 }
75
76 }
4.1进度类(servlet)
@WebServlet("/ProgressServlet")
13 public class ProgressServlet extendsHttpServlet {
14 private static final long serialVersionUID = 1L;
15
16 public ProgressServlet() {
17 super();
18 // TODO Auto-generated constructor stub
19 }
20
21 protected void doGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {
22
23 String id = request.getSession().getId();
24 String filename = request.getParameter("filename");
25 //使用sessionid + 文件名生成文件号,与上传的文件保持一致
26 id = id + filename;
27 Object size = ProgressSingleton.get(id + "Size");
28 size = size == null ? 100 : size;
29 Object progress = ProgressSingleton.get(id + "Progress");
30 progress = progress == null ? 0 : progress;
31 JSONObject json = new JSONObject();
32 json.put("size", size);
33 json.put("progress", progress);
34 response.getWriter().print(json.toString());
35 }
36
37 protected void doPost(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {
38 doGet(request, response);
39 }
40
41 }