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程式碼即可。示例程式碼如下:
- <%@ page language="java"contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <metahttp-equiv="Content-Type"content="text/html; charset=utf-8">
- <title>SWFUpload Demos - Multi-Instance Demo</title>
- <linkhref="css/default.css"rel="stylesheet"type="text/css"/>
- <scripttype="text/javascript"src="swfupload/swfupload.js"></script>
- <scripttype="text/javascript"src="swfupload/swfupload.queue.js"></script>
- <scripttype="text/javascript"src="js/fileprogress.js"></script>
- <scripttype="text/javascript"src="js/handlers.js"></script>
- <scripttype="text/javascript">
- var upload1;
- window.onload = function() {
- upload1 = new SWFUpload({
- // Backend Settings
- upload_url : "upload.jsp",
- post_params : {
- "PHPSESSID" : "123456"
- },
- // File Upload Settings
- file_size_limit : "10000",
- file_types : "*.*",
- file_types_description : "All Files",
- file_upload_limit : 5, // 上傳檔案的總個數
- file_queue_limit : 0, // 每次能上傳的檔案個數
- // 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",
- button_width : 61,
- button_height : 22,
- // Flash Settings
- flash_url : "swfupload/swfupload.swf",
- flash9_url : "swfupload/swfupload_fp9.swf",
- custom_settings : {
- progressTarget : "fsUploadProgress1",
- cancelButtonId : "btnCancel1"
- },
- // Debug Settings
- debug : false
- });
- }
- </script>
- </head>
- <body>
- <divid="header">
- <h1id="logo">
- <ahref="./">SWFUpload</a>
- </h1>
- <divid="version">v2.5.0</div>
- </div>
- <divid="content">
- <h2>Multi-Instance Demo</h2>
- <formid="form1"action="index.jsp"method="post"
- enctype="multipart/form-data">
- <p>This page demonstrates how multiple instances of SWFUpload can
- be loaded on the same page. It also demonstrates the use of the
- graceful degradation plugin and the queue plugin.</p>
- <table>
- <trvalign="top">
- <td>
- <div>
- <divclass="fieldset flash"id="fsUploadProgress1">
- <spanclass="legend">Large File Upload Site</span>
- </div>
- <divstyle="padding-left: 5px;">
- <spanid="spanButtonPlaceholder1"></span><inputid="btnCancel1"
- type="button"value="Cancel Uploads"
- onclick="cancelQueue(upload1);"disabled="disabled"
- style="margin-left: 2px; height: 22px; font-size: 8pt;"/><br/>
- </div>
- </div>
- </td>
- </tr>
- </table>
- </form>
- </div>
- </body>
- </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的部分:
- // 獲取上傳的檔案
- MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
- // 引數Filedata是表單的名字,在swfupload.js中this.ensureDefault("file_post_name", "Filedata");
- MultipartFile multipartFile = multipartRequest.getFile("Filedata");
- String fileName = multipartFile.getOriginalFilename();
- ……
- 將得到的檔案流存入本地伺服器
上面的註釋已經解釋得很清楚了,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程式碼即可,如下是例子:
- <%@ page language="java" contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <%
- response.getWriter().write("返回給客戶端的值");
- %>
如果請求url是個jsp,則可以直接使用out.println("返回值")作為輸出語句。
swfupload在上傳檔案時,會以進度條的方式顯示當前檔案顯示的進度,以及上傳的結果。進度條中的內容可以定製,比如可以顯示上傳速率,已上傳大小,檔案大小,上傳所需時間等等功能。如果是多個檔案同時上傳,則當上傳完成之後,隔幾秒鐘,該進度條會被後面的進度條覆蓋。這裡就有一個問題,如果上傳失敗的檔案,我們需要提示使用者該檔案上傳失敗,以及上傳失敗的原因。但swfupload預設並沒有這樣,它不管你成功失敗,每個進度條在指定的時間間隔後就被後面的進度條覆蓋了。我們通過修改原始碼以滿足定製需求,在fileprogress.js中,找到FileProgress.prototype.setError = function () {}這段程式碼,將如下程式碼遮蔽即可:
[javascript] view plain copy- var oSelf = this;
- this.setTimer(setTimeout(function () {
- oSelf.disappear();
- }, 10000));
最後,因為swfupload是國外的開源控制元件,所以,如果想給使用者展示中文的提示,那就需要使用者自己去漢化。