SpringMVC+Ajax+ajaxFileUpload實現多附件上傳
效果圖如下:
請求提交後儲存至根目錄,以統一信用編碼命名。
1.適用需求:
1)新增附件作為表單的一個輸入項,因此適用於提交表單資訊的同時要上傳附件的情況。(即:附件欄位只作為提交內容的附加資訊)
2)表單通過ajax提交
2)可以上傳多個檔案
2.功能實現所需控制元件/檔案:
1) 輸入型別為file的輸入框:<input type=”file”/>
2)檔案上傳請求指令碼:ajaxFileUpload.js
3.功能點實現思路:
1)功能點:要求點選新增附件的時候彈出檔案選擇框,選擇檔案後,自動新增一行顯示檔名稱與大小(以下簡稱該區域為“檔案資訊塊”)。
思路:仔細想想該部分實現起來並不麻煩,給新增按鈕繫結點選事件,點選事件動態創建出“檔案資訊塊”即可。
注意,“點選新增”與“建立檔案資訊塊”之間有很重要的一步:選擇要上傳的檔案。
選擇上傳檔案視窗是<input type=”file”/>(以下簡稱“檔案輸入框”)點選上傳觸發的,因此我們需要在新增按鈕繫結的事件裡動態生成該控制元件,同時觸發其click事件開啟檔案選擇視窗。當選中檔案後,需要生成對應的“檔案資訊塊”,而“檔案資訊塊”生成的觸發事件就是選擇要上傳的檔案後。即:“檔案輸入框”的onchange()事件。這裡要弄明白,整個過程中我們只調用了“檔案輸入框”的各種事件,實際展示的是“檔案資訊塊”,因此“檔案輸入框”沒必要顯示(設定display:none即可,提交仍能檢測到)
部分程式碼:
/* 新增附件按鈕點選事件 */
$('#addAttachment').on('click',function(){ //addAttachment為新增按鈕的id
var fileId="inputFile"+i;
var str='<input id="'+fileId+'"type="file" calss="'+fileId+'" name="'+fileId+'" data_hideId="'+fileId+'"style="width:150px;height:30px;display:none">';
$(this).parent().append(str);
$("#"+fileId).attr("onchange","showFileArea(this)"); //註冊onchange()方法
document.getElementById(fileId).click(); //立即出發click事件,選擇文//件後觸發onchange()事件
i++;
})
/* 新增“檔案資訊塊”*/
function showFileArea(e){
var fileId=$(e).attr("data_hideId");
var file = $(e).get(0).files[0]; //獲取檔案
var fileName=file.name; //獲取檔名
var fileSize=file.size; //計算檔案大小
if(fileSize>=1024)
fileSize=fileSize/1024 +' MB';
else
fileSize=fileSize+' B';
var str='<div class="inputFileLabel '+fileId+'">'+fileName+'('+fileSize+')'+ //追加“檔案//資訊塊”
'<a class="deleteFile" data_hideId="'+
fileId+
'" onclick="closeFile(this)">x</a>'+
'</div>';
$(e).parent().append(str);
}
以上程式碼利用class和id對標籤進行了標記,方便刪除附件等操作。至此功能點實現。
2)功能點2:點選提交按鈕,實現表單內容(連同附件)的上傳
思路:
點選表單提交的時候,獲取表單內容傳至ajax,並在ajax後臺請求前對檔案進行單獨的請求儲存(ajaxFileUpload)。(這裡之所以在ajax請求裡單獨請求檔案上傳,是因為ajax與後臺傳遞json字串,後臺看到的是檔案的使用者實體地址,不是檔案)
檔案上傳的ajaxFileUpload請求如下:
/* 上傳附件 */
function importFileClick(){
var inputFileArr=$("[class^='inputFile']");
for(var i=0;i<inputFileArr.length;i++){ //迴圈,幾個附件請求幾次
var inputFile=($(inputFileArr.get(i)).attr("class").split(" "))[1];
$.ajaxFileUpload({
url:'abutmentRecord/uploadFile?data='+inputFile,
fileElementId:inputFile, //上傳的檔案id(ajaxFileUpload一次請//求只能上傳一個檔案,需把id傳入;當然,附件多且有能力可以更改js原始碼實現)
secureuri: false,
dataType: 'JSON',
success:function(result){
if(result === 'error'){
layer.msg("附件上傳失敗!",{icon:2});
}else{
}
}
});
}
}
/*表單提交*/
$('#btnSave').on('click', function(){ //點選表單提交按鈕
var data = $('#getFormInfo').getfromdata().data; //獲取表單資訊
importFileClick(); //上傳附件請求
$.ajax({
type:"post",
data:data,
url:'abutment/addSave',
contentType: false,
success:function(data){
//do something ….
},
});
});
3)功能點3:後臺接收前臺的檔案上傳請求
思路:先引入相應的jar包。專案用maven管理,因此只需配置pom.xml。引入jar包後利用對應的類獲取檔案,設定儲存地址,匯出即可。
部分程式碼:
/*pom.xml配置*/
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
/*後臺程式碼*/
@RequestMapping("/uploadFile")
@ResponseBody
public String uploadFile(MultipartHttpServletRequest request){ //注意引數
String result="succed";
try {
String inputFile=this.getPageParameterData().get("data").toString();
CommonsMultipartFile file = (CommonsMultipartFile) request.getFile(inputFile);
String fileName = "檔案字首 -"+file.getOriginalFilename(); //獲取檔名
String realPath = request.getSession().getServletContext().getRealPath("/"+資料夾名); //儲存到專案根目錄的一個資料夾下(注意獲取根目錄地址的方法)
try {
InputStream inputStream = file.getInputStream();
FileUtils.copyInputStreamToFile(inputStream, new File(realPath,fileName));
} catch (IOException e) {
e.printStackTrace();
result="false";
}
} catch (Exception e1) {
e1.printStackTrace();
result="false";
}
return result;
}
}
4.功能實現心得
功能的實現參考了網上大量檔案上傳的資料,但沒有一個是完全適用的,與網上資料最主要的不同是,網上上傳附件是單獨的頁面的功能模組,而本系統除了上傳附件,還有其他資料資訊要提交,且表單資訊通過ajax提交(不是form的submit按鈕提交,因此傳遞的是json字串,檔案無法傳至後臺);因此將功能分解為兩步,附件上傳採用ajaxFileUpload,表單內容採用ajax,在做一些簡單邏輯處理即可。
——————————————————————————————————————————————
ps:轉載分享任意,註明作者和原文連結即可 (●'◡'●)
當然,如果你直接copy程式碼的話很有可能失敗!因為我很多文章只是把部分程式碼貼了出來!而且筆者能力有限,程式碼能夠保證實現功能,但不能保證一定是效能最優的,只提供一個解決問題的大體思路,供大家學習借鑑。如果有什麼錯誤,不足,歡迎指正,一同進步!