jQuery+struts2 實現文件的異步上…

今天準備開始搞搞項目的核心部分——數據導入。
數據導入之前要準備好數據的上傳,struts2爲我們準備了很方便的上傳方法:
直接通過表單把文件上傳到Action中,需要修改表單method爲post,enctype爲multipart/form-data,然後構建一個文件輸入域和一個按鈕
action="upload" method="post" enctype="multipart/form-data"  id="uploadform">
在Action中:

public class UploadAction extends ActionSupport {
private File upload;
private String uploadFileName;
private String uploadContentType;
private String savePath;

public File getUpload() {
return upload;
}

public void setUpload(File upload) {
this.upload = upload;
}

public String getUploadFileName() {
return uploadFileName;
}

public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}

public String getUploadContentType() {
return uploadContentType;
}

public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}

public String getSavePath() {
return ServletActionContext.getServletContext().getRealPath(
"/WEB-INF/" + savePath);
}

public void setSavePath(String savePath) {
this.savePath = savePath;
}

public String execute() throws Exception {
try {
FileInputStream fis = new FileInputStream(getUpload());

FileOutputStream fos = new FileOutputStream("c:\\TEMP" + "\\"
+ getUploadFileName());
int c = -1;
while ((c = fis.read()) != -1) {
fos.write(c);
}
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
ServletActionContext.getResponse().getWriter().print("true");
ServletActionContext.getResponse().getWriter().close();

return null;
}
}

這三個屬性private File upload;
private String uploadFileName;
private String uploadContentType;分別封裝表單裏的文件內容,文件名,文件類型,由struts自動轉換。
Action中的execute用fileinputstream和fileoutputstream來操作文件,其餘的部分和配置跟普通action相似。

第二部分:要實現異步上傳,即上傳時不跳轉頁面,上傳成功後直接在當前頁面提示成功。
項目中我使用的js框架式jQuery,jQuery爲異步傳輸提供了很好的封裝。要實現表單的異步提交,一般需要使用到jQuery.form.js 插件Jquery.form.js
在網上查找了相關資料後瞭解到:
1)這個插件需要jQuery1.5以上;
2)這個插件主要通過ajaxSubmit和ajaxForm兩種方式來實現表單的異步提交,但是要注意不能同時使用兩種方式。

1.         $(“form1”).ajaxSubmit(options)

1)         ajaxSubmitjQuery表單插件核心函數。非常靈活,因爲它依賴於事件機制,只要有事件觸發就能使用ajaxSubmit()提交表單,eg:超鏈接、圖片、按鈕的click事件。

2)         options參數是

a)         一個函數,則爲表單提交成功後調用的回調函數,即,options={success:function}

b)         options參數是一個集合,一個參數鍵值對

鍵名

描述

type

(默認爲表單的method屬性值,若未設置取GET

請求的類型,例如:POSTGETPUTPROPFIND。大小寫不敏感。

url

(默認取表單的action屬性值,若未設置默認取window.location.href

請求的URL地址,可以爲絕對地址也可以爲相對地址。

data

(對象成員必須包含namevalue屬性)提供額外數據對象,通過$.param()函數返回序列化後的字符串,稍後會拼接到表單元素序列化的字符串之後。

extraData

(此參數無需外部提供,由內部處理)

此參數是data在進行序列化成字符串之前的一個拷貝,只用於在表單包含並且是老瀏覽器。

因爲在老瀏覽器中文件上傳文件我們需要通過來模擬異步提交,此時extraData會轉變爲元素包含在表單中,被一起提交到服務器。

dataType

一般不需自己設置。參數作用請看:jQuery.ajax()-dataType

traditional

如果你想要用傳統的方式來序列化數據,那麼就設置爲true。請參考$.param()深度遞歸詳解

delegation

(適用於ajaxFormajaxForm支持Jquery插件的委託方式(需要Jquery v1.7+),所以當你調用ajaxForm的時候其表單form不一定存在,但動態構建的form會在適當的時候調用ajaxSubmitEg


        $('#myForm').ajaxForm({ 
            delegation: true,
            target: '#output'
        });  

replaceTarget

(默認:false)與target參數共同起作用,True則執行replaceWirh()函數,false則執行html()函數

target

提供一個Html元素,在請求成功並且未設置dataType參數,則將返回的數據replaceWith()html()掉對象原來的內容,再遍歷對象調用success回調函數。


    if (!options.dataType && options.target) {
        var oldSuccess = options.success || function(){};
        callbacks.push(function(data) {
            var fn = options.replaceTarget ? 'replaceWith' : 'html';
            $(options.target)[fn](data).each(oldSuccess, arguments);
        });
    }

includeHidden

在請求成功後,若設置執行clearForm()函數清空表單元素則會根據includeHidden設置決定如何清空隱藏域元素。

1)         傳遞true,表示清空表單的所有隱藏域元素。

2)         傳遞字符串,表示清空特殊匹配的隱藏域表單元素,eg$('#myForm').clearForm('.special:hidden'),清空class屬性包含special值的隱藏域

clearForm

請求成功時觸發(同success),並用options. includeHidden做爲回調函數參數。

回調函數:$form.clearForm(options.includeHidden);

resetForm

請求成功時觸發(同success)。

回調函數:$form.resetForm()

semantic

布爾值,指示表單元素序列化時是否嚴格按照表單元素定義順序。

在序列化只有元素會放在序列化字符串的最後,若semantic=true,則會按照它的定義順序進行序列化。

若你服務器嚴格要求表單序列化字符串的順序,則使用此參數進行控制。

iframe

(默認:false)若有文件上傳'input[type=file]:enabled[value!=""]',指示是否應該使用標籤(在支持html5文件上傳新特性的瀏覽器中不會使用iframe模式)

iframeTarget

指定一個現有的元素,否則將自動生成一個元素以及name屬性值。若現有的元素沒有設置name屬性,則會自動生成一個name

iframeSrc

元素設定src屬性值

 

回調函數

beforeSerialize

提供在將表單元素序列化爲字符串之前,處理表單元素的回調函數。

簽名:function(form,options)

函數說明:當前表單對象、options參數集合

返回值:返回false,表示終止表單提交操作。

beforeSubmit

提供在執行表單提交之前,處理數據的回調函數。

簽名:function(a,form,options)

函數說明:通過formToArray(options.semantic, elements)返回的表單元素數組、當前表單對象、options參數集合

返回值:返回false,表示終止表單提交操作。

3)         $(“form1”).ajaxSubmit(options) 內部直接或模擬jQuery.ajax(options)異步提交,所以也直接支持jQuery.ajax(options)所能處理的參數,並且支持jQuery.ajax(options)過程中所觸發的5局部事件6全局事件

4)         $(“form1”).ajaxSubmit(options) 內部將內部直接調用jQuery.ajax(options)返回的jqxhr對象或模擬的jqxhr對象進行了緩存,所以我們可以通過$(“#form1”).data(‘jqxhr’)獲取到本次提交生成的jqxhr對象。

5)         更多jQuery.ajax()函數介紹請看:觸碰jQueryAJAX異步詳解

 

ajaxSubmit函數處理流程:

1)         根據

處理urltype參數以及successiframeSrc等參數。

2)         觸發beforeSerialize()回調函數

3)         序列化data參數和表單元素

4)         觸發beforeSubmit()回調函數

5)         根據type參數處理options.dataoptions.url參數

6)         註冊resetForm()clearForm()回調函數

7)         註冊將返回數據加載到options.target指定的元素上的回調函數

8)         註冊success回調函數,若有options.target則循環該元素,併爲每個子元素註冊success回調函數

9)         處理文件上傳元素

a)         不包含文件元素,直接調用jQuery.ajax()函數。

b)         包含文件元素,並且不支持XMLHttpRequest Level 2提供的文件上傳新特性window.FormData。則通過IFrame模擬表單異步提交

                                       i.              調用fileUploadIframe()函數。

                                     ii.              根據options. iframeTarget設置決定是創建一個元素還是使用現有的元素

                                    iii.              模擬xhr對象以及jQuery.ajax()過程,以支持xhr對象返回和ajax事件觸發

                                    iv.              設置

target指向元素、encodingenctype“multipart/form-data”method”post”值等等

                                     v.              處理options.extraData元素並添加到

元素中。

                                    vi.              調用

submit()事件。(同步提交,但因爲 target指向標籤,所以刷新的是中的內容,以此模擬異步提交)

c)         包含文件元素,並且支持XMLHttpRequest Level 2提供的新特性,則調用fileUploadXhr()函數,通過FormData()對象將數據傳遞給options.data參數,再調用jQuery.ajax(options)函數異步提交表單。並且XMLHttpRequest Level 2的新特性還支持進度條提示功能。(更多新特性請看:XMLHttpRequest Level 2 使用指南

10)     將內部jqxhr緩存起來,以供訪問。$form.removeData('jqxhr').data('jqxhr', jqxhr);

11)     返回表單元素本身,以便符合jQuery的鏈式操作模式。

2.         $(“form1”).ajaxForm(options)

是對$(“any”).ajaxSubmit(options)函數的一個封裝,適用於表單提交的方式(注意,主體對象是

),會幫你管理表單的submit和提交元素([type=submit],[type=image])的click事件。在出發表單的submit事件時:阻止submit()事件的默認行爲(同步提交的行爲)並且調用$(this).ajaxSubmit(options)函數。

ajaxForm支持Jquery插件的委託方式(需要Jquery v1.7+


需要注意的是ajaxForm()並不是直接提交表單,而是爲提交表單做異步的準備。ajaxForm()

增加所有需要的事件監聽函數,爲AJAX提交表單做好準備。ajaxForm不能提交表單。在document的ready函數中,使用 ajaxForm來爲AJAX提交表單進行準備。ajaxForm接受0個或1個參數。這個單個的參數既可以是一個回調函數,也可以是一個Options 對象。

是否可鏈接(Chainable):可以。

實例:

1 $('#myFormId').ajaxForm();

ajaxSubmit()

馬上由AJAX來提交表單。大多數情況下,都是調用ajaxSubmit來對用戶提交表單進行響應。ajaxSubmit接受0個或1個參數。這個單個的參數既可以是一個回調函數,也可以是一個Options對象。

是否可鏈接(Chainable):可以。

實例:

1 //綁定表單提交事件處理器
2 $('#myFormId').submit(function() {
3     // 提交表單
4     $(this).ajaxSubmit();
5     // 爲了防止普通瀏覽器進行表單提交和產生頁面導航(防止默認提交)返回false
6     return false;
7 });
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章