admin管理员组文章数量:1325497
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.
The form looks like this:
<form:form mandName="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;
}
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;
}
The bean:
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;
}
}
And the controller:
@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.
}
How can I make files
correctly append to formData
?
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.
The form looks like this:
<form:form mandName="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;
}
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;
}
The bean:
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;
}
}
And the controller:
@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.
}
How can I make files
correctly append to formData
?
-
1
Just a shot in the dark - instead of
append
ing once, try appending multiple times (for all files), providing the samename
. And for thename
, I'd suggest something likefiles[]
, because that usually signifies to the server that it contains a list and can show up multiple times in the request payload – Ian Commented Mar 18, 2014 at 14:33 -
Tried that just now, with
'files[]'
and with'files[' + i + ']'
, and it never hits the controller. – Zook Commented Mar 18, 2014 at 14:49 -
1
However, doing exactly that with
'files'
for the name makes everything work. Thanks! If you write it up as an answer I'll accept it. – Zook Commented Mar 18, 2014 at 14:55 -
Sorry, I meant that if you changed it to
files[]
, you'd have to change your property in yourDocumentsBean
class to reflect that. Usingi
wouldn't help and would actually break my point. But I'm glad my overall suggestion helped/worked! – Ian Commented Mar 18, 2014 at 15:52
1 Answer
Reset to default 8In 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;
}
本文标签: javascriptHow do I send an array of files using xhr2 and FormData (JavaSpring)Stack Overflow
版权声明:本文标题:javascript - How do I send an array of files using xhr2 and FormData? (Java + Spring) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742197942a2431426.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论