【问题标题】:How do I send an array of files using xhr2 and FormData? (Java + Spring)如何使用 xhr2 和 FormData 发送文件数组? (Java + 弹簧)
【发布时间】:2014-04-24 07:11:15
【问题描述】:

我正在使用<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>

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

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

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?

【问题讨论】:

  • 只是在黑暗中拍摄 - 而不是 appending 一次,尝试多次附加(对于所有文件),提供相同的 name。对于name,我建议使用files[] 之类的东西,因为这通常向服务器表明它包含一个列表并且可以在请求有效负载中多次显示
  • 刚才试过了,用'files[]'和'files[' + i + ']',它从来没有碰到控制器。
  • 然而,以'files' 为名,一切正常。谢谢!如果你把它写成答案,我会接受。
  • 对不起,我的意思是如果你把它改成files[],你必须在你的DocumentsBean类中改变你的属性来反映这一点。使用i 无济于事,实际上会打破我的观点。但我很高兴我的整体建议有所帮助/奏效!

标签: java javascript html spring-mvc xmlhttprequest


【解决方案1】:

为了让 Spring 将请求中的项目映射到列表,您需要在附加到表单数据时为每个项目提供相同的 name(在 FormData.append 调用中)。这使得 Spring 可以有效地将请求视为name=value1&amp;name=value2&amp;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;
}

【讨论】:

    猜你喜欢
    • 2021-11-05
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2011-10-23
    • 1970-01-01
    相关资源
    最近更新 更多