J'ai la méthode de contrôleur suivante pour télécharger plusieurs fichiers à la fois, inspirée par cet article de blog et les réponses à cette question aussi:
@RequestMapping(value = "/{user}/attachment", method = RequestMethod.POST)
@PreAuthorize(...)
public void upload(@PathVariable User user,
@RequestParam("file") List<MultipartFile> files) {
// handle files
}
Cependant, la liste des fichiers est toujours vide même si la requête les contient.
Si j'ajoute le troisième paramètre MultipartRequest
à la méthode:
public void upload(@PathVariable User user,
@RequestParam("file") List<MultipartFile> files,
MultipartRequest request)
Je peux voir qu'il contient mes fichiers téléchargés correctement:
Quelle pourrait être la raison de List<MultipartFile>
vide?
J'utilise ng-file-upload pour soumettre les fichiers, mais je ne pense pas que cela soit lié au problème. Printemps 4.2.4.
Le problème était que ng-file-upload par défaut soumet un tableau de fichiers utilisant les noms file[0]
, file[1]
, etc. Il est configurable avec la valeur arrayKey
en utilisant le service Upload
. Le fait de le définir sur chaîne vide force l'envoi des fichiers sous la même clé file
, qui est correctement résolue avec Spring et dont la fonction @RequestParam("file") List<MultipartFile>
contient tous les fichiers soumis.
Upload.upload({url: url, data: {file: arrayOfFiles}, arrayKey: ''})
Essayez d'utiliser @ModelAttribute
comme ceci:
@RequestMapping(value = "/{user}/attachment", method = RequestMethod.POST)
@PreAuthorize(...)
public void upload(@PathVariable User user,@ModelAttribute("uploadFile") FileUpload uploadFile) throws IllegalStateException, IOException {
List<MultipartFile> files = uploadFile.getFiles();
...
Et créez une classe comme:
public class FileUpload {
private List<MultipartFile> files;
public List<MultipartFile> getFiles() {
return files;
}
public void setFiles(List<MultipartFile> files) {
this.files= files;
}
}
Cela fonctionne pour moi, envoyer de gros objets 'email' avec plusieurs pièces jointes de l'interface utilisateur au back-end
Angular
sendEmailWithAttachments(taskId: string, template: string, email: any, modelConfig: any, files: any[]) {
let formData = new FormData();
formData.append('form', new Blob([JSON.stringify(email)], {type: 'application/json'}));
files.forEach(file => {
formData.append('files', file);
});
return this.$http({
method: 'POST',
data: formData,
url: this.baseUrl + '/' + taskId + '/email-with-attachment?template=' + template,
headers: {
'Content-Type': undefined
},
responseType: 'arraybuffer'
});
}
Java Spring
@RequestMapping(value = "{taskId}/email-with-attachment", method = RequestMethod.POST, consumes = MULTIPART_FORM_DATA_VALUE)
public void sendEmailWithAttachment(
@PathVariable String taskId,
@RequestParam String template,
@RequestParam("form") MultipartFile form,
@RequestParam("files") List<MultipartFile> files) throws IOException {
Map<String, String> parameters = new ObjectMapper().readValue(form.getInputStream(), HashMap.class);
System.out.println("taskId", taskId);
System.out.println("template", template);
System.out.println("files", files);
System.out.println("parameters", parameters);
}
Je pense que de la manière dont vous avez envoyé les données de face, il ne peut pas bound avec Java.util.List. Si vous créez une donnée JSON en tant que demande et que vous annotez votre liste avec @RequestBody, comme suit:
@RequestMapping(value = "/{user}/attachment", method = RequestMethod.POST)
@PreAuthorize(...)
public void upload(@PathVariable User user,
@RequestBody List<MultipartFile> files) {
// handle files
}
ça devrait marcher. Quelques infos ici .