1. 程式人生 > >Spring + Ajax 同時傳輸文字和檔案

Spring + Ajax 同時傳輸文字和檔案

需求:上傳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
    }
}