如何使用 xhr2 和 FormData 发送文件数组?(Java + 弹簧) [英] How do I send an array of files using xhr2 and FormData? (Java + Spring)

查看:34
本文介绍了如何使用 xhr2 和 FormData 发送文件数组?(Java + 弹簧)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 上传文件列表.这可以正常工作,但我希望能够在上传之前删除单个文件,因此我将 FileList 存储在一个单独的对象中并通过 xhr 路由它.但是,它不起作用.

I'm using <input type="file" multiple /> to upload a list of files. This works fine as is, but I want the ability to remove individual files before upload, so I'm storing the FileList in a separate object and routing it through xhr. However, it doesn't work.

表格如下所示:

<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>

这是处理它的函数(工作版本):

Here's the function that handles it (working version):

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;
}

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

And the non-working version, where I try to stick the files into the formData manually:

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;
}

豆子:

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;
    }
}

和控制器:

@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.
}

如何使 files 正确附加到 formData?

How can I make files correctly append to formData?

推荐答案

为了让 Spring 将请求中的项目映射到列表中,您需要提供相同的 name(在 FormData.append 在附加到表单数据时为每个项目调用).这允许 Spring 有效地将请求视为 name=value1&name=value2&name=value3(但显然是以表单数据的形式).当 Spring 多次看到相同的键(名称")时,它可以将这些值映射到一个集合中.以您的示例为例,需要 name files",因为您的 DocumentsBean 以这种方式命名.这意味着您的 JavaScript 代码应该更改为如下所示:

In order for Spring to map items in a request to a list, you need to provide the same name (in the FormData.append calls) for each item when appending to the form data. This allows Spring to effectively see the request as name=value1&name=value2&name=value3 (but obviously in the form of form data). When Spring sees the same key ("name") multiple times, it can map the values into a collection. Going with your example, the name "files" is needed because your DocumentsBean has named it that way. That means your JavaScript code should change to be something like this:

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;
}

这篇关于如何使用 xhr2 和 FormData 发送文件数组?(Java + 弹簧)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆