Téléchargement de fichiers avec Spring MVC

1. Vue d'ensemble

Dans les articles précédents, nous avons présenté les bases de la gestion des formulaires et exploré la bibliothèque de balises de formulaire dans Spring MVC.

Dans cet article, nous nous concentrons sur ce que Spring propose pour la prise en charge en plusieurs parties (téléchargement de fichiers) dans les applications Web.

Spring nous permet d'activer cette prise en charge en plusieurs parties avec des objets MultipartResolver enfichables . Le framework fournit une implémentation MultipartResolver à utiliser avec Commons FileUpload et une autre à utiliser avec l' analyse des requêtes en plusieurs parties Servlet 3.0 .

Après avoir configuré le MultipartResolver, nous verrons comment télécharger un seul fichier et plusieurs fichiers.

Nous aborderons également Spring Boot.

2. Fichier Commons

Pour utiliser CommonsMultipartResolver pour gérer le téléchargement du fichier, nous devons ajouter la dépendance suivante:

 commons-fileupload commons-fileupload 1.3.1 

Nous pouvons maintenant définir le bean CommonsMultipartResolver dans notre configuration Spring.

Ce MultipartResolver est livré avec une série de méthodes set pour définir des propriétés telles que la taille maximale des téléchargements:

@Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(100000); return multipartResolver; }

Ici, nous devons contrôler différentes propriétés de CommonsMultipartResolver dans la définition de Bean elle-même.

3. Avec Servlet 3.0

Pour utiliser l' analyse en plusieurs parties du Servlet 3.0 , nous devons configurer quelques éléments de l'application. Tout d'abord, nous devons définir un MultipartConfigElement dans notre enregistrement DispatcherServlet :

public class MainWebAppInitializer implements WebApplicationInitializer { private String TMP_FOLDER = "/tmp"; private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; @Override public void onStartup(ServletContext sc) throws ServletException { ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet( new GenericWebApplicationContext())); appServlet.setLoadOnStartup(1); MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2); appServlet.setMultipartConfig(multipartConfigElement); } }

Dans l' objet MultipartConfigElement , nous avons configuré l'emplacement de stockage, la taille maximale du fichier individuel, la taille maximale de la demande (dans le cas de plusieurs fichiers dans une seule demande) et la taille à laquelle la progression du téléchargement du fichier est vidée vers l'emplacement de stockage.

Ces paramètres doivent être appliqués au niveau d'enregistrement du servlet, car Servlet 3.0 ne leur permet pas d'être enregistré dans MultipartResolver comme c'est le cas avec CommonsMultipartResolver.

Une fois que cela est fait, nous pouvons ajouter le StandardServletMultipartResolver à notre configuration Spring:

@Bean public StandardServletMultipartResolver multipartResolver() { return new StandardServletMultipartResolver(); }

4. Téléchargement d'un fichier

Pour télécharger notre fichier, nous pouvons créer un formulaire simple dans lequel nous utilisons une balise d' entrée HTML avec type = 'file'.

Quelle que soit la configuration de gestion du téléchargement que nous avons choisie, nous devons définir l'attribut de codage du formulaire sur multipart / form-data. Cela permet au navigateur de savoir comment encoder le formulaire:


    
Select a file to upload

Pour stocker le fichier téléchargé, nous pouvons utiliser une variable MultipartFile . Nous pouvons récupérer cette variable à partir du paramètre de requête dans la méthode de notre contrôleur:

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST) public String submit(@RequestParam("file") MultipartFile file, ModelMap modelMap) { modelMap.addAttribute("file", file); return "fileUploadView"; } 

La classe MultipartFile permet d'accéder aux détails sur le fichier téléchargé , y compris le nom de fichier, le type de fichier, etc. Nous pouvons utiliser une simple page HTML pour afficher ces informations:

Submitted File

OriginalFileName: ${file.originalFilename}
Type: ${file.contentType}

5. Téléchargement de plusieurs fichiers

Pour télécharger plusieurs fichiers en une seule demande, nous plaçons simplement plusieurs champs de fichier d'entrée dans le formulaire:


    
Select a file to upload
Select a file to upload
Select a file to upload

Nous devons veiller à ce que chaque champ d'entrée ait le même nom afin qu'il soit accessible en tant que tableau de MultipartFile :

@RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST) public String submit(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) { modelMap.addAttribute("files", files); return "fileUploadView"; } 

Maintenant, nous pouvons simplement parcourir ce tableau pour afficher les informations sur les fichiers:

   Spring MVC File Upload   

Submitted Files

OriginalFileName: ${file.originalFilename}
Type: ${file.contentType}

6. Téléchargement de fichiers avec des données de formulaire supplémentaires

Nous pouvons également envoyer des informations supplémentaires au serveur avec le fichier en cours de téléchargement. Il suffit d'inclure les champs obligatoires dans le formulaire:


    
Name
Email
Select a file to upload

Dans le contrôleur, nous pouvons obtenir toutes les données du formulaire en utilisant l' annotation @RequestParam :

@PostMapping("/uploadFileWithAddtionalData") public String submit( @RequestParam MultipartFile file, @RequestParam String name, @RequestParam String email, ModelMap modelMap) { modelMap.addAttribute("name", name); modelMap.addAttribute("email", email); modelMap.addAttribute("file", file); return "fileUploadView"; }

Comme dans les sections précédentes, nous pouvons utiliser la page HTML avec des balises JSTL pour afficher les informations.

Nous pouvons également encapsuler tous les champs de formulaire dans une classe de modèle et utiliser l' annotation @ModelAttribute dans le contrôleur. Cela serait utile lorsqu'il y a beaucoup de champs supplémentaires avec le fichier. Regardons le code:

public class FormDataWithFile { private String name; private String email; private MultipartFile file; // standard getters and setters }
@PostMapping("/uploadFileModelAttribute") public String submit(@ModelAttribute FormDataWithFile formDataWithFile, ModelMap modelMap) { modelMap.addAttribute("formDataWithFile", formDataWithFile); return "fileUploadView"; }

7. Téléchargement du fichier Spring Boot

Si nous utilisons Spring Boot, tout ce que nous avons vu jusqu'à présent s'applique toujours.

Cependant, Spring Boot rend encore plus facile la configuration et le démarrage de tout avec peu de tracas.

In particular, it's not necessary to configure any servlet, as Boot will register and configure it for us, provided that we include the web module in our dependencies:

 org.springframework.boot spring-boot-starter-web 2.1.8.RELEASE 

We can find the latest version of spring-boot-starter-web on Maven Central.

If we want to control the maximum file upload size, we can edit our application.properties:

spring.servlet.multipart.max-file-size=128KB spring.servlet.multipart.max-request-size=128KB

We can also control whether file uploading is enabled, and the location for file upload:

spring.servlet.multipart.enabled=true spring.servlet.multipart.location=${java.io.tmpdir}

Note that we've used ${java.io.tmpdir} to define the upload location so that we can use the temporary location for different operating systems.

8. Conclusion

Dans cet article, nous avons examiné différentes façons de configurer la prise en charge de plusieurs parties dans Spring. Grâce à ces derniers, nous pouvons prendre en charge les téléchargements de fichiers dans nos applications Web.

L'implémentation de ce tutoriel se trouve dans un projet GitHub. Lorsque le projet s'exécute localement, l'exemple de formulaire est accessible à l'adresse // localhost: 8080 / spring-mvc-java / fileUpload