Spring + Ajax 同時傳輸文字和檔案
阿新 • • 發佈:2018-11-05
需求:上傳docx檔案,輸入待替換的 人名、地名或組織名 ,然後在後端執行替換,再非同步返回給前端下載
直接將檔案和文字拼接賦給data屬性測試失敗
Html:
<div id="page2" class="col s12" style="margin-top: 5%;margin-bottom: 5%"> <form action="#" name="fileForm" id="selectFile" enctype="multipart/form-data"> <div class="file-field input-field" style="margin: 5% auto; text-align: center;width: 50%"> <div class="waves-effect waves-light btn z-depth-2 light-blue darken-3"> <span>選擇檔案</span> <input id="fileChooser" accept=".docx,application/msword" name="file" type="file"> </div> <div class="input-field" style="margin-left: 50px"> <input class="file-path validate" type="text"> </div> </div> </form> <div class="file-field input-field" style="margin: 5% auto; text-align: center;"> <span> 替換選項: </span> <span> <input type="checkbox" class="filled-in" id="PER" checked/> <label for="PER">人名</label> <input id="newPER" type="text" style="width:20%"> </span> <span> <input type="checkbox" class="filled-in" id="LOC" /> <label for="LOC">地名</label> <input id="newLOC" type="text" style="width:20%"> </span> <span> <input type="checkbox" class="filled-in" id="ORG" /> <label for="ORG">組織名</label> <input id="newORG" type="text" style="width:20%"> </span> </div> <div class="input-field" style="margin: 5% auto; text-align: center"> <button type="submit" id="submit-btn2" class="waves-effect waves-light btn z-depth-2 light-blue darken-3">提交</button> </div> </div>
主要就是把form的enctype屬性設定為 multipart/formdata ,然後設定action="#" 以便使用ajax傳送請求
js:
$("#submit-btn2").click(function() { var selectedFile=new FormData($('#selectFile')[0]); var newPER=$("#newPER").val(); var newLOC=$("#newLOC").val(); var newORG=$("#newORG").val(); selectedFile.append("newPER",newPER); selectedFile.append("newLOC",newLOC); selectedFile.append("newORG",newORG); $.ajax({ type: 'post', url: '/uploadFile', cache: false, async: true, data: selectedFile, processData:false, contentType:false, beforeSend: function () { …… }, error:function (){ …… }, success: function (result) { …… } }); });
首先將整個form包裹進FormData物件中,然後獲取文字框中的值,使用append方法也包裝進FormData物件,將整個物件賦給data屬性
後臺:
@PostMapping("/uploadFile") public WebAsyncTask<String> upload(@RequestParam(value="file") MultipartFile file,@RequestParam(value="choice") int choice,@RequestParam(value="newPER") String newPER,@RequestParam(value="newLOC") String newLOC,@RequestParam(value="newORG") String newORG){ //把上傳的檔案儲存到本地 File newFile=new File(System.getProperty("user.dir")+"/upload/"+file.getOriginalFilename()); file.transferTo(newFile); …… }
之後對newFile操作即可
由於檔案處理是耗時操作,於是使用WebAsyncTask非同步返回結果,接受一個Callable<T>物件
ajax的success處可以根據返回值進行後續處理,比如我這裡返回一個字串,如果處理過程中丟擲異常,則返回"error";否則返回"修改-原始檔名",用來作為下載檔案時的引數:
success: function (result) {
$('#processing').hide();
if(result=="error"){
$('#funcTabs').show();
alert('檔案處理失敗!請檢查檔案格式或網路。')
}else {
$('#processFinished').show();
document.getElementById('processedFile').value = result
}
}