如何使用xhr2和FormData发送文件数组?(Java +春季)

Zoo*_*ook 1 javascript java html5 xmlhttprequest spring-mvc

<input type="file" multiple />用来上传文件列表。这样可以正常工作,但是我希望能够在上传之前删除单个文件,因此我将FileList单独存储在一个对象中并通过xhr进行路由。但是,它不起作用。

该表格如下所示:

<form:form commandName="documentsBean" enctype="multipart/form-data">
    <input type="hidden" name="submittedFormAction" value="attachDocumentSave"/>
    <input type="file" name="files" id="attachFiles" multiple/>
    <button type="submit" id="attachButton" onclick="return buildForm(this.form);">Attach</button>
</form:form>
Run Code Online (Sandbox Code Playgroud)

这是处理它的功能(工作版本):

function buildForm(form){
    var formData = new FormData(form);
    formData.append('testString', "foobar");

    var xhr = new XMLHttpRequest();
    xhr.open('POST', form.action, true);
    xhr.send(formData);

    return false;
}
Run Code Online (Sandbox Code Playgroud)

非工作版本,我尝试将文件手动粘贴到formData中:

function buildForm(form){
    var files = document.getElementById('attachFiles').files;

    // var tempfiles = [];
    // for(var i=0; i<files.length; i++){
    //     tempfiles[i]=files[i];
    // }

    var formData = new FormData();
    formData.append('submittedFormAction', "attachDocumentSave");
    formData.append('files', files);  // still broken with formData.append('files', tempfiles);
    formData.append('testString', "foobar");

    var xhr = new XMLHttpRequest();
    xhr.open('POST', form.action, true);
    xhr.send(formData);

    return false;
}
Run Code Online (Sandbox Code Playgroud)

豆:

public class DocumentsBean
{
    private List<MultipartFile> files = Arrays.asList();
    private String testString = "";

    public List<MultipartFile> getFiles(){
        return files;
    }
    public void setFiles(List<MultipartFile> files){
        this.files = files;
    }
    public String getTestString(){
        return testString;
    }
    public void setTestString(String testString){
        this.testString = testString;
    }
}
Run Code Online (Sandbox Code Playgroud)

和控制器:

@RequestMapping( method = RequestMethod.POST, params = { "submittedFormAction=attachDocumentSave" })
public ModelAndView attachDocumentSave(HttpServletRequest request, @ModelAttribute("documentsBean") DocumentsBean documentsBean, BindingResult errors) throws Exception
{
    // Drilling into documentsBean here with the working version shows:
    //
    //     files= LinkedList<E>  (id=78)
    //         first= LinkedList$Node<E>  (id=94)
    //         last= LinkedList$Node<E>  (id=96)
    //         modCount= 3
    //         size= 3
    //     testString= "foobar" (id=84)
    //
    // and it successfully uploads the 3 files.

    // Drilling into documentsBean here with the non-working version shows:
    //
    //     files= Arrays$ArrayList<E>  (id=116)
    //         a= MultipartFile[0]  (id=121)
    //         modCount= 0
    //     testString= "foobar" (id=119)
    //
    // and it does not upload the files.
}
Run Code Online (Sandbox Code Playgroud)

如何files正确附加formData

Ian*_*Ian 6

为了使Spring将请求中的项目映射到列表,在附加到表单数据时nameFormData.append需要为每个项目提供相同的内容(在调用中)。这使Spring可以将请求有效地视为name=value1&name=value2&name=value3(但显然是以表单数据的形式)。当Spring多次看到相同的键(“名称”)时,它可以将值映射到一个集合中。在您的示例中,name“文件”是必需的,因为您DocumentsBean已经用这种方式命名了。这意味着您的JavaScript代码应更改为以下形式:

function buildForm(form) {
    var files, formData, i, j, xhr;

    files = document.getElementById('attachFiles').files;
    formData = new FormData();

    formData.append('submittedFormAction', "attachDocumentSave");
    for (i = 0, j = files.length; i < j; i++) {
        formData.append('files', files[i]);
    }
    formData.append('testString', "foobar");

    xhr = new XMLHttpRequest();
    xhr.open('POST', form.action, true);
    xhr.send(formData);

    return false;
}
Run Code Online (Sandbox Code Playgroud)