SpringBoot: Téléchargement de gros fichiers en streaming à l'aide d'Apache Commons FileUpload
Suis en train de télécharger un fichier volumineux en utilisant le 'streaming' Apache Commons Upload de Fichier API.
La raison pour laquelle je suis à l'aide de l'Apache Commons Fichier à Uploader et pas la valeur par défaut Printemps Multipart uploader est qu'elle ne tient pas quand on télécharger des fichiers très volumineux (~2 GO). Je travaille sur une application SIG, où de tels téléchargements de fichiers sont assez communs.
Le code complet de mon upload de fichier contrôleur est comme suit:
@Controller
public class FileUploadController {
@RequestMapping(value="/upload", method=RequestMethod.POST)
public void upload(HttpServletRequest request) {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
//Inform user about invalid request
return;
}
//String filename = request.getParameter("name");
//Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
//Parse the request
try {
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
System.out.println("Form field " + name + " with value " + Streams.asString(stream) + " detected.");
} else {
System.out.println("File field " + name + " with file name " + item.getName() + " detected.");
//Process the input stream
OutputStream out = new FileOutputStream("incoming.gz");
IOUtils.copy(stream, out);
stream.close();
out.close();
}
}
}catch (FileUploadException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
@RequestMapping(value = "/uploader", method = RequestMethod.GET)
public ModelAndView uploaderPage() {
ModelAndView model = new ModelAndView();
model.setViewName("uploader");
return model;
}
}
Le problème est que la getItemIterator(request)
toujours retourne un itérateur qui ne dispose pas de tous les éléments (c'est à dire iter.hasNext()
) renvoie toujours false
.
Ma demande.fichier de propriétés est comme suit:
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:19095/authdb
spring.datasource.username=georbis
spring.datasource.password=asdf123
logging.level.org.springframework.web=DEBUG
spring.jpa.hibernate.ddl-auto=update
multipart.maxFileSize: 128000MB
multipart.maxRequestSize: 128000MB
server.port=19091
La JSP en vue de la /uploader
est comme suit:
<html>
<body>
<form method="POST" enctype="multipart/form-data" action="/upload">
File to upload: <input type="file" name="file"><br />
Name: <input type="text" name="name"><br /> <br />
Press here to upload the file!<input type="submit" value="Upload">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</body>
</html>
Quoi pourrais-je fait de mal?
source d'informationauteur balajeerc
Vous devez vous connecter pour publier un commentaire.
Grâce à quelques commentaires par M. Deinum, j'ai réussi à résoudre le problème. J'ai nettoyé certains de mes post et mets en ligne ce qu'une réponse complète pour référence future.
La première erreur que je faisais n'était pas la désactivation par défaut
MultipartResolver
que le Printemps offre. Cela a fini dans le résolveur de traitement de laHttpServeletRequest
et donc de les consommer avant mon contrôleur peut agir sur elle.Le moyen de le désactiver, merci à M. Deinum a été comme suit:
Cependant, il y a encore un autre écueil caché en attente pour moi après cela. Dès que j'ai désactivé par défaut multipart de résolution, j'ai commencé à avoir l'erreur suivante en essayant de faire un upload:
Dans ma configuration de la sécurité, j'avais activé la protection CSRF. Que fallait que j'envoie ma demande de publication de la façon suivante:
J'ai aussi modifié mon contrôleur un peu:
lorsque la Réponse est juste un simple générique type de réponse que j'utilise:
Si vous utilisez une version récente de printemps de démarrage (je suis à l'aide de la version 2.0.0.M7) ensuite, la propriété, les noms ont changé.
Le printemps a commencé à utiliser la technologie des noms spécifiques
Si vous avez de la StreamClosed exceptions causé par de multiples implémentations d'être actif, alors la dernière option vous permet de désactiver par défaut le printemps de la mise en œuvre
S'il vous plaît essayez d'ajouter
spring.http.multipart.enabled=false
dans application.propriétés fichier.- Je utiliser kindeditor + springboot. Lorsque j'utilise (MultipartHttpServletRequest) demande. J'ai pu récupérer le fichier, mais j'utilise appeche-commune-io:télécharger.parse(demande) la valeur de retour est nulle.