使用jQuery+SWFUpload+Commons-FileUpload实现带进度条的上传

 

注:摘自http://theoffspring.iteye.com/blog/1480092,这里只是做个备份,供自己学习使用!

 

这两天在找一个可以实现上传时显示进度的ajax库,看了很多10 best ajax uploader之类的文章,发现里面很多链接都点不进去,或者网站文档和demo做得很烂,我这人选开源软件用,一定会看他的文档做得怎么样,做得不全就懒得研究了,swfupload文档做得也不好,例子太少,没有讲解,不过本着矬子里面拔高个的原则只能将就着用它了。外国有个人实现了一个swfuload的jquery插件,主要是完善swfupload的事件机制的,可以点这里去看看,结合这个插件,做多文件上传加进度条是件很easy的事情。官网的例子偏偏没有后端是java的例子,我又google了一番,试用了一下commons-fileupload,感觉很方便,于是就整出了一个例子来,前端是参照这个做了些修改。btw,iteye有好几篇是讲swfupload+java实现上传的,后端是个jsp自己实现的保存上传文件的,我下载了一下代码,发现一模一样,也不知是谁抄谁的,都宣称原创,好笑。

 

1.前面选择上传文件的页面upload.jsp

 

Xml代码    收藏代码
  1. <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
  2.          pageEncoding="ISO-8859-1" %>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6.     <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
  7.     <title>Insert title here</title>  
  8.     <link href="css/default.css" rel="stylesheet" type="text/css"/>  
  9.     <script type="text/javascript" src="js/swfupload.js"></script>  
  10.     <script type="text/javascript" src="js/swfupload.queue.js"></script>  
  11.     <script type="text/javascript" src="js/fileprogress.js"></script>  
  12.     <script type="text/javascript" src="js/handlers.js"></script>  
  13.     <script type="text/javascript" src="js/jquery-1.4.3.js"></script>  
  14.     <script type="text/javascript" src="js/jquery.swfupload.js"></script>  
  15.   
  16.     <style type="text/css">  
  17.         #swfupload-control p {  
  18.             margin: 10px 5px;  
  19.             font-size: 0.9em;  
  20.         }  
  21.   
  22.         #log {  
  23.             margin: 0;  
  24.             padding: 0;  
  25.             width: 500px;  
  26.         }  
  27.   
  28.         #log li {  
  29.             list-style-position: inside;  
  30.             margin: 2px;  
  31.             border: 1px solid #ccc;  
  32.             padding: 10px;  
  33.             font-size: 15px;  
  34.             font-family: Arial, Helvetica, sans-serif;  
  35.             color: #333;  
  36.             background: #fff;  
  37.             position: relative;  
  38.         }  
  39.   
  40.         #log li .progressbar {  
  41.             border: 1px solid #333;  
  42.             height: 18px;  
  43.             background: #fff;  
  44.         }  
  45.   
  46.         #log li .progress {  
  47.             background: rgba(104, 133, 127, 0.52);  
  48.             width: 0%;  
  49.             height: 18px;  
  50.         }  
  51.   
  52.         #log li p {  
  53.             margin: 0;  
  54.             line-height: 18px;  
  55.         }  
  56.   
  57.         #log li.success {  
  58.             border: 1px solid #339933;  
  59.             background: #ccf9b9;  
  60.         }  
  61.   
  62.         #log li span.stopUpload {  
  63.             position: absolute;  
  64.             top: 5px;  
  65.             right: 5px;  
  66.             width: 20px;  
  67.             height: 20px;  
  68.             background: url('js/swfupload/cancel.png') no-repeat;  
  69.             cursor: pointer;  
  70.         }  
  71.   
  72.         #img span.cancel {  
  73.             background: url('js/swfupload/cancel.png') no-repeat;  
  74.         }  
  75.     </style>  
  76.   
  77.     <script type="text/javascript">  
  78.         $(function () {  
  79.             $('#swfupload-control').swfupload({  
  80.                 upload_url:"handler/doUpload",  
  81.                 file_post_name:'uploadfile',  
  82.                 file_size_limit:"20000 MB",  
  83.                 file_types:"*.*",  
  84.                 file_types_description:"All files",  
  85.                 flash_url:"js/swfupload.swf",  
  86.                 button_image_url:'js/swfupload/wdp_buttons_upload_114x29.png',  
  87.                 button_width:114,  
  88.                 button_height:29,  
  89.                 button_placeholder:$('#button')[0],  
  90.             })  
  91.                     .bind('fileQueued', function (event, file) {  
  92.                         var listitem = '<li id="' + file.id + '" >' +  
  93.                                 'File: <em>' + file.name + '</em> (' + Math.round(file.size / 1024) + ' KB) <span class="progressvalue" ></span>' +  
  94.                                 '<div class="progressbar" ><div class="progress" ></div></div>' +  
  95.                                 '<p class="status" >Pending</p>' +  
  96.                                 '<span class="stopUpload" >&nbsp;</span>' +  
  97.                                 '</li>';  
  98.                         $('#log').append(listitem);  
  99.                         $('li#' + file.id + ' .stopUpload').bind('click', function () { //Remove from queue on cancel click  
  100.                             var swfu = $.swfupload.getInstance('#swfupload-control');  
  101.                             swfu.cancelUpload(file.id);  
  102.                             $('#log li#' + file.id).find('p.status').text('Canceled');  
  103.                             $('#log li#' + file.id).find('span.stopUpload').css('background-image','none')  
  104.                             $('#log li#' + file.id).find('span.stopUpload').css('cursor','defult')  
  105. //                            $('li#' + file.id).slideUp('fast');  
  106.                         });  
  107.                         // start the upload since it's queued  
  108.                         $(this).swfupload('startUpload');  
  109.                     })  
  110.                     .bind('fileQueueError', function (event, file, errorCode, message) {  
  111.                         //alert('Size of the file '+file.name+' is greater than limit');  
  112.                         alert(errorCode+":"+message)  
  113.   
  114.                     })  
  115.                     .bind('fileDialogComplete', function (event, numFilesSelected, numFilesQueued) {  
  116.                         $('#queuestatus').text('Files Selected: ' + numFilesSelected + ' / Queued Files: ' + numFilesQueued);  
  117.                     })  
  118.                     .bind('uploadStart', function (event, file) {  
  119.                         $('#log li#' + file.id).find('p.status').text('Uploading...');  
  120.                         $('#log li#' + file.id).find('span.progressvalue').text('0%');  
  121.                         $('#log li#' + file.id).find('span.cancel').hide();  
  122.                     })  
  123.                     .bind('uploadProgress', function (event, file, bytesLoaded) {  
  124.                         //Show Progress  
  125.                         var percentage = Math.round((bytesLoaded / file.size) * 100);  
  126.                         $('#log li#' + file.id).find('div.progress').css('width', percentage + '%');  
  127.                         $('#log li#' + file.id).find('span.progressvalue').text(percentage + '%');  
  128.                     })  
  129.                     .bind('uploadSuccess', function (event, file, serverData) {  
  130.                         var item = $('#log li#' + file.id);  
  131.                         item.find('div.progress').css('width', '100%');  
  132.                         item.find('span.progressvalue').text('100%');  
  133.                         item.addClass('success').find('p.status').html('Done!!! ');  
  134.                         $('#log li#' + file.id).find('span.stopUpload').css('background-image','none') ;  
  135.                         $('#log li#' + file.id).find('span.stopUpload').css('cursor','default') ;  
  136.                     })  
  137.                     .bind('uploadComplete', function (event, file) {  
  138.                         // upload has completed, try the next one in the queue  
  139.                         $(this).swfupload('startUpload');  
  140.                     })  
  141.         });  
  142.     </script>  
  143. </head>  
  144. <body>  
  145.   
  146. <div id="swfupload-control">  
  147.     <p>Select files of any type, muliple files are allowed to select every time.</p>  
  148.     <input type="button" id="button"/>  
  149.   
  150.     <p id="queuestatus"></p>  
  151.     <ol id="log"></ol>  
  152. </div>  
  153. </body>  
  154. </html>  

 取消按钮的那个class如果叫cancel(原始例子是叫这个名字的),是不好用的,html里总是有一些诡异的保留字在等着我们,我改成stopUpload就好用了。

 

 2.后端保存文件的servlet

 

Java代码    收藏代码
  1. package com.offspring.servlet;  
  2.   
  3.   
  4. import org.apache.commons.fileupload.FileItem;  
  5. import org.apache.commons.fileupload.FileUploadException;  
  6. import org.apache.commons.fileupload.disk.DiskFileItemFactory;  
  7. import org.apache.commons.fileupload.servlet.ServletFileUpload;  
  8.   
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11. import java.io.File;  
  12. import java.io.IOException;  
  13. import java.util.Iterator;  
  14. import java.util.List;  
  15.   
  16. public class Upload extends javax.servlet.http.HttpServlet {  
  17.     public static final int MB = 1024 * 1024;  
  18.   
  19.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {  
  20.   
  21.         DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(10 * MB, new File("d:/temp4"));  
  22.         ServletFileUpload uploader = new ServletFileUpload(fileItemFactory);  
  23.         uploader.setSizeMax(1200 * MB);  
  24.         List fields = null;  
  25.         try {  
  26.             fields = uploader.parseRequest(request);  
  27.         } catch (FileUploadException e) {  
  28.             e.printStackTrace();  
  29.             return;  
  30.         }  
  31.         Iterator iter = fields.iterator();  
  32.         while (iter.hasNext()) {  
  33.             FileItem item = (FileItem) iter.next();  
  34.   
  35.             if (!item.isFormField()) {  
  36.                 try {  
  37.                     processUploadedFile(item);  
  38.                 } catch (Exception e) {  
  39.                     e.printStackTrace();  
  40.                    return;  
  41.                 }  
  42.             }  
  43.         }  
  44.   
  45.         response.getOutputStream().println("200 OK");  
  46.   
  47.   
  48.     }  
  49.   
  50.     private void processUploadedFile(FileItem item) throws Exception {  
  51.         String basePath = "d:\\temp\\upload\\";  
  52.         item.write(new File(basePath + item.getName()));  
  53.         System.out.println("write file to '"+basePath + item.getName()+"'");  
  54.     }  
  55.   
  56. }  

 运行时截图:

 
使用jQuery+SWFUpload+Commons-FileUpload实现带进度条的上传_第1张图片
 你同时选多个文件也是可以的,不过仍然一次上传一个,一个传完了,下一个会自动开启上传。

 

3.实现进度条的原理

   swfupload提供了很多事件,结合jquery可以绑定相应的回调函数, 比如uploadProgress会在上传过程中定期被触发,你在这个回调里写个用css更新进度条宽度就OK了。

 

  • flashReady
  • swfUploadLoaded
  • fileDialogStart
  • fileQueued
  • fileQueueError
  • fileDialogComplete
  • uploadStart
  • uploadProgress
  • uploadError
  • uploadSuccess
  • uploadComplete 
  •  

    Js代码    收藏代码
    1. .bind('uploadProgress'function (event, file, bytesLoaded) {  
    2.   //Show Progress  
    3.  var percentage = Math.round((bytesLoaded / file.size) * 100);  
    4.  $('#log li#' + file.id).find('div.progress').css('width', percentage + '%');  
    5.  $('#log li#' + file.id).find('span.progressvalue').text(percentage + '%');  
    6.   })  

     
    不过记得在linux上 uploadProgress 只会在上传结束时才触发,这是linux上flash的一个bug。本来写得很多,在firefox上上传附件不好用,然后文字还变成了乱码,这是怎么搞的?

     

    你可能感兴趣的:(使用jQuery+SWFUpload+Commons-FileUpload实现带进度条的上传)