1. 程式人生 > >swfupload多檔案上傳控制元件的使用

swfupload多檔案上傳控制元件的使用

swfupload是一個基於flash的多檔案上傳元件,前端是採用javascript指令碼編寫的,它與flash指令碼進行互動,以實現多檔案的上傳功能。因前端是js指令碼,所以在做web頁面整合時很方便,以下通過對swfupload自帶的demo進行一些修改,以實現簡單的多檔案上傳功能。然後再簡單介紹下,通過修改js原始碼,以滿足不同的個性化需要。

         swfupload目前的最新版本是v2.2.0.1,其官方原始碼地址:http://code.google.com/p/swfupload/,demo線上演示地址:http://demo.swfupload.org/v220/index.htm。該頁面提供了多種上傳演示介面,以適應不同的應用場景,這裡不一一介紹。下載原始碼和demo的例子之後,在samples包中有demos和samples兩個子資料夾。開啟demos子目錄,其下包含多個demo,因原始碼中的demo都是採用的php編寫的,在這裡,我們以multiinstancedemo作為模版,對其進行簡單的改造,實現一個java編寫的多檔案上傳的功能。

        首先介紹下demo的目錄結構,在multiinstancedemo中包含如下檔案:

        js目錄中包含兩個js檔案:fileprogress.js和handlers.js,這兩個檔案的作用從名字上就能大概知道一些了,fileprogress.js主要是用來控制檔案上傳時的進度條顯示的功能,而handlers.js則是配合fileprogress.js對檔案上傳時的各種處理功能。

       其中,index.php是用於顯示上傳元件的前端頁面,upload.php則是當index.php頁面點選上傳按鈕之後,將檔案上傳進行處理的頁面。js目錄裡的兩個js檔案則是在index.php頁面中引用的兩個js檔案,最後那個圖片資原始檔,則是一個表示不同狀態下的上傳按鈕。注意,這裡僅介紹了multiinstancedemo目錄下的檔案,它們僅僅是一些前端處理的功能,真正的核心並不在這裡,所以在該專案中,還需要其他的幾個資原始檔才能實現多檔案上傳的功能。通過開啟index.php檔案可以看到它還引用了其他的一些核心資源,從以下程式碼中就能看出來。


        從以上程式碼中,我們可以看到,除了上面介紹的fileprogress.js和handlers.js檔案之外,還有swfuoload.js、swfupload.queue.js,這兩個檔案則是與上傳相關的功能了,比如前期驗證,上傳檔案的個性化設定等等功能。除了js檔案,還有一個css樣式檔案,控制頁面以及控制條的顯示樣式等,這裡就不作詳細介紹。最後,剩下最重要的兩個flash控制元件swfupload.swf和swfupload_fp9.swf,它們表示支援不同的flash版本,具體的介紹請看官方文件。但是swfupload也有個限制,不支援低於某個版本的flash,實際使用該控制元件時,一旦檢測到低於該版本時,將會彈出相應的提示。

       在這裡再多說一句,以上僅僅是介紹了multiinstancedemo需要的必備檔案,實際上,swfupload的不同demo中使用的檔案不盡相同。因此,其他的檔案功能在本文中不作介紹,欲知詳情,請自行閱讀官方文件。好了,言歸正傳, 既然已經知道一個完整的多檔案上傳需要哪些必備的控制元件,接下來就是動手改造專案的過程了。首先新建一個java的web專案,然後將上面提到的幾個資原始檔在webcontent中部署好,包括index.php和upload.php檔案。然後將index.php改成index.jsp,並修改其原始碼,將php部分的原始碼都刪掉,僅留下html程式碼即可。示例程式碼如下:

  1. <%@ page language="java"contentType="text/html; charset=utf-8"
  2.     pageEncoding="utf-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <metahttp-equiv="Content-Type"content="text/html; charset=utf-8">
  7. <title>SWFUpload Demos - Multi-Instance Demo</title>
  8. <linkhref="css/default.css"rel="stylesheet"type="text/css"/>
  9. <scripttype="text/javascript"src="swfupload/swfupload.js"></script>
  10. <scripttype="text/javascript"src="swfupload/swfupload.queue.js"></script>
  11. <scripttype="text/javascript"src="js/fileprogress.js"></script>
  12. <scripttype="text/javascript"src="js/handlers.js"></script>
  13. <scripttype="text/javascript">
  14.     var upload1;  
  15.     window.onload = function() {  
  16.         upload1 = new SWFUpload({  
  17.             // Backend Settings  
  18.             upload_url : "upload.jsp",  
  19.             post_params : {  
  20.                 "PHPSESSID" : "123456"  
  21.             },  
  22.             // File Upload Settings  
  23.             file_size_limit : "10000",  
  24.             file_types : "*.*",  
  25.             file_types_description : "All Files",  
  26.             file_upload_limit : 5,  // 上傳檔案的總個數  
  27.             file_queue_limit : 0,   // 每次能上傳的檔案個數  
  28.             // Event Handler Settings (all my handlers are in the Handler.js file)  
  29.             swfupload_preload_handler : preLoad,  
  30.             swfupload_load_failed_handler : loadFailed,  
  31.             file_dialog_start_handler : fileDialogStart,  
  32.             file_queued_handler : fileQueued,  
  33.             file_queue_error_handler : fileQueueError,  
  34.             file_dialog_complete_handler : fileDialogComplete,  
  35.             upload_start_handler : uploadStart,  
  36.             upload_progress_handler : uploadProgress,  
  37.             upload_error_handler : uploadError,  
  38.             upload_success_handler : uploadSuccess,  
  39.             upload_complete_handler : uploadComplete,  
  40.             // Button Settings  
  41.             button_image_url : "XPButtonUploadText_61x22.png",  
  42.             button_placeholder_id : "spanButtonPlaceholder1",  
  43.             button_width : 61,  
  44.             button_height : 22,  
  45.             // Flash Settings  
  46.             flash_url : "swfupload/swfupload.swf",  
  47.             flash9_url : "swfupload/swfupload_fp9.swf",  
  48.             custom_settings : {  
  49.                 progressTarget : "fsUploadProgress1",  
  50.                 cancelButtonId : "btnCancel1"  
  51.             },  
  52.             // Debug Settings  
  53.             debug : false  
  54.         });  
  55.     }  
  56. </script>
  57. </head>
  58. <body>
  59.     <divid="header">
  60.         <h1id="logo">
  61.             <ahref="./">SWFUpload</a>
  62.         </h1>
  63.         <divid="version">v2.5.0</div>
  64.     </div>
  65.     <divid="content">
  66.         <h2>Multi-Instance Demo</h2>
  67.         <formid="form1"action="index.jsp"method="post"
  68.             enctype="multipart/form-data">
  69.             <p>This page demonstrates how multiple instances of SWFUpload can  
  70.                 be loaded on the same page. It also demonstrates the use of the  
  71.                 graceful degradation plugin and the queue plugin.</p>
  72.             <table>
  73.                 <trvalign="top">
  74.                     <td>
  75.                         <div>
  76.                             <divclass="fieldset flash"id="fsUploadProgress1">
  77.                                 <spanclass="legend">Large File Upload Site</span>
  78.                             </div>
  79.                             <divstyle="padding-left: 5px;">
  80.                                 <spanid="spanButtonPlaceholder1"></span><inputid="btnCancel1"
  81.                                     type="button"value="Cancel Uploads"
  82.                                     onclick="cancelQueue(upload1);"disabled="disabled"
  83.                                     style="margin-left: 2px; height: 22px; font-size: 8pt;"/><br/>
  84.                             </div>
  85.                         </div>
  86.                     </td>
  87.                 </tr>
  88.             </table>
  89.         </form>
  90.     </div>
  91. </body>
  92. </html>

這裡簡要介紹下程式碼中的幾個要點:

upload_url : "upload.jsp", 上傳檔案的後臺處理url,這裡就是upload.jsp。如果是採用的j2ee,這裡可以是具體的連結或者相對路徑,比如http://xxx/xxx/upload.do等等。

post_params : {"PHPSESSID" : "123456"}, 提交的url時,可附帶一些引數。

// File Upload Settings
file_size_limit : "10000", 檔案上傳的大小限制,0表示無限制。
file_types : "*.*", 檔案上傳的格式限制,當前表示無限制。
file_types_description : "All Files",  上傳的檔案描述。
file_upload_limit : 5,  上傳檔案的總個數。
file_queue_limit : 0,   每次能上傳的檔案個數,0表示無限制,但是他會受到上傳總個數的限制。

以下是一些事件的設定,這些方法都在handlers.js中,這裡我們不對其修改。
// Event Handler Settings (all my handlers are in the Handler.js file)
swfupload_preload_handler : preLoad,
swfupload_load_failed_handler : loadFailed,
file_dialog_start_handler : fileDialogStart,
file_queued_handler : fileQueued,
file_queue_error_handler : fileQueueError,
file_dialog_complete_handler : fileDialogComplete,
upload_start_handler : uploadStart,
upload_progress_handler : uploadProgress,
upload_error_handler : uploadError,
upload_success_handler : uploadSuccess,
upload_complete_handler : uploadComplete,

// Button Settings
button_image_url : "XPButtonUploadText_61x22.png", 上傳按鈕的圖片
button_placeholder_id : "spanButtonPlaceholder1",  上傳按鈕的id值,與下面的html程式碼相關聯
button_width : 61,  按鈕寬度
button_height : 22,  按鈕的高度


以下是對flash版本的設定
// Flash Settings
flash_url : "swfupload/swfupload.swf",
flash9_url : "swfupload/swfupload_fp9.swf",


以下是對上傳進度條的設定
custom_settings : {
progressTarget : "fsUploadProgress1",  與上面的上傳按鈕一樣,該值與html相關聯
cancelButtonId : "btnCancel1"  取消上傳的按鈕,與html相關聯
},

// Debug Settings
debug : false  swfupload支援debug的模式

         接下來,我們編寫上傳的檔案處理程式碼,也就是把上傳的檔案存入本地伺服器的程式碼,java中實現的方式有很多種,比如使用smartupload或者是其他的方式都可以,這裡只列出涉及到swfupload的部分:

  1. // 獲取上傳的檔案
  2. MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;  
  3. // 引數Filedata是表單的名字,在swfupload.js中this.ensureDefault("file_post_name", "Filedata");
  4. MultipartFile multipartFile = multipartRequest.getFile("Filedata");  
  5. String fileName = multipartFile.getOriginalFilename();  
  6.                          ……  
  7.                       將得到的檔案流存入本地伺服器  

        上面的註釋已經解釋得很清楚了,multipartRequest.getFile("Filedata");中的引數需要獲取上傳檔案的表單的名字。通常,我們在定義上傳檔案的表單時,一般都是這樣寫:<input type="file" name="fileName" />請選擇要上傳的檔案,這裡的表單名字就是fileName。而在index.jsp中,按鈕是引用的id佔位的方式,在js上也沒有顯式定義表單名,所以通過原始碼,我們可以看到表單的名字在swfupload.js中的預設定義:this.ensureDefault("file_post_name", "Filedata");。因此,方法中的引數就是FileData,當然,如果在index.jsp中顯式定義該表單的名字,則方法中應該填寫修改過後的名字。顯式定義的方法很簡單,在index.jsp的js部分,我們把該屬性定義在upload_url : "upload.jsp",程式碼之後,具體位置沒有限制,只要定義在new SWFUpload()之中就可以,如:file_post_name: "fileName",就這麼一行程式碼就完成了顯式定義。

        按照上面的步驟完善過後,一個簡單的多檔案上傳功能基本大功告成了。接下來再簡單介紹下swfupload的其他幾個方面,其實,swfupload的多檔案上傳,僅僅是可以選擇多個檔案,但是在上傳的處理過程中,它是每上傳一個檔案就呼叫一次upload.jsp頁面。可以做一個簡單的測試,通過multipartFile物件可以獲取上傳檔案的個數,或者是將

String fileName = multipartFile.getOriginalFilename();中定義的fileName打印出來,結果是隻有一個檔案。

        在上面的例子中,我們並沒有將伺服器端的處理結果返回給前端頁面,而swfupload是支援返回伺服器端的結果給前端的。伺服器端返回的資料儲存在handlers.js中的uploadSuccess(file, serverData)方法中的serverData引數中。這裡需要注意,上傳的處理頁面的返回資料應儘量簡單,如果處理頁面是一個帶有html標籤的頁面,那麼將同時返回這些標籤欄位。既然是處理頁面,那麼無須使用者訪問該頁面。因此,如無特殊要求,處理頁面應儘可能避免加入html標籤,僅新增java程式碼即可,如下是例子:

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2.     pageEncoding="utf-8"%>  
  3. <%  
  4. response.getWriter().write("返回給客戶端的值");  
  5. %>  

如果請求url是個jsp,則可以直接使用out.println("返回值")作為輸出語句。

         swfupload在上傳檔案時,會以進度條的方式顯示當前檔案顯示的進度,以及上傳的結果。進度條中的內容可以定製,比如可以顯示上傳速率,已上傳大小,檔案大小,上傳所需時間等等功能。如果是多個檔案同時上傳,則當上傳完成之後,隔幾秒鐘,該進度條會被後面的進度條覆蓋。這裡就有一個問題,如果上傳失敗的檔案,我們需要提示使用者該檔案上傳失敗,以及上傳失敗的原因。但swfupload預設並沒有這樣,它不管你成功失敗,每個進度條在指定的時間間隔後就被後面的進度條覆蓋了。我們通過修改原始碼以滿足定製需求,在fileprogress.js中,找到FileProgress.prototype.setError = function () {}這段程式碼,將如下程式碼遮蔽即可:

[javascript] view plain copy
  1. var oSelf = this;  
  2. this.setTimer(setTimeout(function () {  
  3.     oSelf.disappear();  
  4. }, 10000));  

       最後,因為swfupload是國外的開源控制元件,所以,如果想給使用者展示中文的提示,那就需要使用者自己去漢化。