请客官参考http://blog.itpub.net/30066956/viewspace-1775286/ 这一篇文章,来决定使用哪儿种,个人觉得使用uploadify更好更方便。
感谢:http://blog.sina.com.cn/s/blog_674b23220100he8x.html ,本文参考了很多这篇博文中的内容。
摘要:
在web项目中,经常会有文件上传需求。有时会遇到上传很大的文件,需要时间比较长。这样如果在界面上给用户一个进度条展示上传进度,会大大增加用户使用的方便。
struts进行文件上传时,前台进度显示的一种解决方案。
Struts2 进度条 文件上传 progressbar easyui
2G,实际用户上传的数据文件大小一般也不会太小,再加上如果网速慢的话,等待时间可能会很长。所以要为这个功能加上进度条,让用户在等待过程中, 了解自己数据上传进度。
先上效果图
解决步骤。
1、 前台进度条控件选择使用easyui 的progressbar控件。
详细的使用说明参考官网文档:http://www.jeasyui.com/documentation/index.php
所有需要引入jquery-1.11.1.min.js 以及jquery.easyui.min.js
2、 前台显示控件有了,下面需要提供一个后台方法,来供前台查询上传进度。(使用Struts2自带的文件上传,它集成了commons-fileupload)
3、 在上传文件时,不断的向后台请求目前的进度,改变进度条控件的值。
实现监控到文件上传进度
下面的重点在于如何使用commons-fileupload进行文件上传时使用进度。
http://commons.apache.org/proper/commons-fileupload/using.html 在这个官方文档中搜索 Watching progress 可以得到详细的指导。
点击(此处)折叠或打开
1. //Create a progress listener
2. ProgressListener progressListener = new ProgressListener(){
3. public void update(long pBytesRead, long pContentLength, int pItems) {
4. System.out.println(“We are currently reading item “ + pItems);
5. if (pContentLength == -1) {
6. System.out.println(“So far, “ + pBytesRead + ” bytes have been read.”);
7. } else {
8. System.out.println(“So far, “ + pBytesRead + ” of “ + pContentLength
9. + ” bytes have been read.”);
10. }
11. }
12. };
13. upload.setProgressListener(progressListener);
先创建一个实现了ProgressListener接口的对象,然后对upload对象发出增加监听器消息。
但问题是,我们是使用了Struts2 进行文件上传。而Struts2在文件上传的处理的类过程中并没有为我们加一个这样的监听器。
解决办法:(参考http://blog.sina.com.cn/s/blog_674b23220100he8x.html)
找到org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类的代码。
自己写个类实现MyMultiPartRequest把
org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest的代码copy进来再修改parseRequest 这个方法的实现,加上监听部分。把进度信息放到Session中
这是我的项目中修改后的parseRequest方法。
点击(此处)折叠或打开
1. private List<FileItem> parseRequest(HttpServletRequest servletRequest,
2. String saveDir) throws FileUploadException {
3.
4. UploadStatus status = new UploadStatus(); // 上传状态
5. UploadListener listner = new UploadListener(status); // 监听器
6. servletRequest.getSession().setAttribute(“uploadStatus”, status); // 把状态放到session里去
7.
8. DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
9. ServletFileUpload upload = new ServletFileUpload(fac);
10. upload.setSizeMax(maxSize);
11. upload.setProgressListener(listner);// 添加监听器
12.
13. return upload.parseRequest(createRequestContext(servletRequest));
14. }
点击(此处)折叠或打开
- public class UploadListener implements ProgressListener {
- private UploadStatus status;
- public UploadListener(UploadStatus status) {
- this.status = status;
- }
- public void update(long bytesRead, long contentLength, int items) {
- // 上传组件会调用该方法
- status.setBytesRead(bytesRead); // 已读取的数据长度
- status.setContentLength(contentLength); // 文件总长度
- status.setItems(items); // 正在保存第几个文件
- }
- }
点击(此处)折叠或打开
1. public class UploadStatus {
2.
3. private long bytesRead; // 已经上传的字节数,单位:字节
4. private long contentLength; // 所有文件的总长度,单位:字节
5. private int items; // 正在上传第几个文件
6. private long startTime = System.currentTimeMillis(); // 开始上传的时间,用于计算上传速度等
7. public long getBytesRead() {
8. return bytesRead;
9. }
10. public void setBytesRead(long bytesRead) {
11. this.bytesRead = bytesRead;
12. }
13. public long getContentLength() {
14. return contentLength;
15. }
16. public void setContentLength(long contentLength) {
17. this.contentLength = contentLength;
18. }
19. public int getItems() {
20. return items;
21. }
22. public void setItems(int items) {
23. this.items = items;
24. }
25. public long getStartTime() {
26. return startTime;
27. }
28. public void setStartTime(long startTime) {
29. this.startTime = startTime;
30. }
31.
32. }
还需要配置一下,让Struts2使用我们自己写的MyMultiPartRequest
点击(此处)折叠或打开
1. <constant name=“struts.multipart.parser” value=“com.hengyun.action.uploadprocess.MyMultiPartRequest” />
2. <constant name=“struts.multipart.handler” value=“com.hengyun.action.uploadprocess.MyMultiPartRequest” />
3. <constant name=“struts.multipart.maxSize” value=“2000000000”/>
取得进度信息
经过上面的工作,现在在上传文件时,Session已经有了UploadStatus 对象了。
可以实现一个action,从Session中取进度信息,返回前台。
项目中action 代码,可以用做参考
点击(此处)折叠或打开
1. /**
2. * 显示文件上传的进度
3. */
4. public String getFileUploadProgress(){
5. ActionContext cxt = ActionContext.getContext();
6. HttpServletResponse response = (HttpServletResponse)cxt.get(ServletActionContext.HTTP_RESPONSE);
7.
8. UploadStatus status = (UploadStatus)SessionUtil.getObjectFromSession(“uploadStatus”);
9.
10. if(status == null){
11. return “fail”;
12. }
13.
14. long startTime = status.getStartTime(); //上传开始时间
15. long currentTime = System.currentTimeMillis(); //现在时间
16. long time = (currentTime - startTime)/ 1000 + 1; //已传输的时间 单位:s
17.
18. //传输速度单位:byte/s
19. double velocity = ((double)status.getBytesRead()) / (double)time;
20. //估计总时间
21. double totalTime = status.getContentLength();
22. //估计剩余时间
23. double timeLeft = totalTime - time;
24. //已经完成的百分比
25. int percent = (int)(100 * (double)status.getBytesRead() / (double)status.getContentLength());
26. //已经完成数单位:m
27. double length = ((double) status.getBytesRead())/1024/1024;
28. //总长度 单位:m
29. double totalLength = ((double) status.getContentLength())/1024/1024;
30.
31. ret.put(“percent”, String.valueOf(percent));
32. ret.put(“length”, String.valueOf(length));
33. ret.put(“totalLength”,String.valueOf( totalLength));
34. ret.put(“velocity”, String.valueOf(velocity));
35. ret.put(“time”, String.valueOf(time));
36. ret.put(“totalTime”, String.valueOf(totalTime));
37. ret.put(“timeLeft”, String.valueOf(timeLeft));
38. ret.put(“fileNumber”, String.valueOf(status.getItems()));
39. return “success”;
40. }
demo贴上来,以供参考吧。
点击(此处)折叠或打开
1. <%@ page language=“java” import=“java.util.*” pageEncoding=“UTF-8”%>
2. <%
3. String path = request.getContextPath();
4. String basePath = request.getScheme()+“://”+request.getServerName()+“:”+request.getServerPort()+path+“/”;
5. %>
6.
7. <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
8. <html>
9. <style type=“text/css”>
10. #progressBar{width:400px;height:12px;background:#FFFFFF;border:1px solid #000000; padding: 1px;}
11. #progressBarItem{width:0%; height:100%;background:#FF0000}
12. </style>
13. <link rel=“stylesheet” type=“text/css” href=“css/easyui.css”>
14. <link rel=“stylesheet” type=“text/css” href=“css/demo.css”>
15. <link rel=“stylesheet” type=“text/css” href=“css/icon.css”>
16.
17.
18. <script type=“text/javascript” src=“js/jquery-1.11.1.min.js”></script>
19. <script type=“text/javascript” src=“js/jquery.easyui.min.js”></script>
20. <script type=“text/javascript” src=“js/json/json_parse_state.js”></script>
21. <script type=“text/javascript” src=“js/main.js”></script>
22.
23.
24.
25.
26. <script>
27. function showUploadProgress(processbarid){
28. var url =‘test/test_doFileProgress.action?radom=’+Math.random();
29. var dataObj = $.ajax({
30. url : url,
31. async : false
32. });
33.
34. var myObject = json_parse(dataObj.responseText);
35. $(“[id=”+processbarid+“]”).progressbar(‘setValue’, myObject.percent);
36. setTimeout(arguments.callee, 500);
37. };
38.
39. function uploadData() {
40. showUploadProcess(“fileuploadprocessbar”)
41. $(‘#uploadData’).form(‘submit’, {
42. url : ‘data/dataAction_saveData.action’,
43. success : function(data) {
44. $(‘#uploadData’).form(‘clear’);
45. }
46. });
47. }
48. </script>
49. </head>
50. <body>
51. <form id=“uploadData” method=“post” action=“data/dataAction_saveData.action” enctype=“multipart/form-data”“>
52.
53. <div class=”content“>
54. <table border=”0” cellspacing=”1” cellpadding=”0” width=”100%” class=”tk_table“>
55. <tr>
56. <td>文件上传:</td>
57. <td><input type=”file” name=”file” size=”28” /></td>
58. </tr>
59. <tr>
60. <td>进度<td/>
61. <td><div id=”fileuploadprocessbar” class=”easyui-progressbar” style=”width:400px;background-color:‘ff0000’“></div> </td>
62. </tr>
63. </table>
64. </div>
65. <div class=”bottombtn“>
66. <table width=”40%” class=”btntalbe“>
67. <tr>
68. <td align=”center“>
69. <input id=”btnOk” type=”submit” value=”确定” class=”tkbtn surebt” οnclick=”uploadData()“/></td>
70. <td align=”center“>
71. <input type=”button” class=”closeB tkbtn” value=”取消
only one.它就是 :
showUploadProgress(processbarid);
processbarid 为前台processbar 控件的id。