我正在使用<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
?
答案 0 :(得分:5)
为了让Spring将请求中的项目映射到列表,您需要在附加到表单数据时为每个项目提供相同的name
(在FormData.append
调用中)。这允许Spring有效地将请求视为name=value1&name=value2&name=value3
(但显然是以表单数据的形式)。当Spring多次看到相同的键(&#34; name&#34;)时,它可以将值映射到集合中。继续你的例子,name
&#34;文件&#34;是必需的,因为你的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;
}