Téléchargement de fichiers avec des servlets et JSP

1. Introduction

Dans ce rapide tutoriel, nous verrons comment télécharger un fichier à partir d'un servlet.

Pour y parvenir, nous allons d'abord voir la solution vanilla Jakarta EE avec des capacités de téléchargement de fichiers fournies par l' annotation native @MultipartConfig .

Ensuite, nous passerons en revue la bibliothèque Apache Commons FileUpload , pour les versions antérieures de l'API Servlet.

2. Utilisation de Jakarta EE @MultipartConfig

Jakarta EE a la capacité de prendre en charge les téléchargements en plusieurs parties dès la sortie de la boîte.

En tant que tel, il s'agit probablement d'une option par défaut lors de l'enrichissement d'une application Jakarta EE avec la prise en charge du téléchargement de fichiers.

Tout d'abord, ajoutons un formulaire à notre fichier HTML:

 Choose a file:   

Le formulaire doit être défini à l'aide de l' attribut enctype = "multipart / form-data" pour signaler un téléchargement en plusieurs parties.

Ensuite, nous voudrons annoter notre HttpServlet avec les informations correctes à l'aide de l' annotation @MultipartConfig :

@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5) public class MultipartServlet extends HttpServlet { //... } 

Ensuite, assurons-nous que notre dossier de téléchargement de serveur par défaut est défini:

String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; File uploadDir = new File(uploadPath); if (!uploadDir.exists()) uploadDir.mkdir(); 

Enfin, nous pouvons facilement récupérer notre fichier entrant à partir de la requête en utilisant la méthode getParts () , et l'enregistrer sur le disque:

for (Part part : request.getParts()) { fileName = getFileName(part); part.write(uploadPath + File.separator + fileName); } 

Notez que, dans cet exemple, nous utilisons une méthode d'assistance getFileName ():

private String getFileName(Part part) { for (String content : part.getHeader("content-disposition").split(";")) { if (content.trim().startsWith("filename")) return content.substring(content.indexOf("=") + 2, content.length() - 1); } return Constants.DEFAULT_FILENAME; }

Pour Servlet 3.1. projets, nous pourrions également utiliser la méthode Part.getSubmittedFileName () :

fileName = part.getSubmittedFileName();

3. Utilisation d'Apache Commons FileUpload

Si nous ne sommes pas sur un projet Servlet 3.0, nous pouvons utiliser directement la bibliothèque Apache Commons FileUpload.

3.1. Installer

Nous souhaitons utiliser les dépendances pom.xml suivantes pour exécuter notre exemple:

 commons-fileupload commons-fileupload 1.3.3   commons-io commons-io 2.6 

Les versions les plus récentes peuvent être trouvées avec une recherche rapide sur le référentiel central de Maven: commons-fileupload et commons-io.

3.2. Télécharger le servlet

Les trois parties principales de l'incorporation de la bibliothèque FileUpload d'Apache sont les suivantes:

  • Un formulaire de téléchargement dans une page .jsp .
  • Configuration de votre objet DiskFileItemFactory et ServletFileUpload .
  • Traitement du contenu réel d'un téléchargement de fichier en plusieurs parties.

Le formulaire de téléchargement est le même que celui de la section précédente.

Passons à la création de notre servlet Jakarta EE.

Dans notre méthode de traitement des requêtes, nous pouvons encapsuler la HttpRequest entrante avec une vérification pour voir s'il s'agit d'un téléchargement en plusieurs parties.

Nous spécifierons également les ressources à allouer au téléchargement du fichier temporairement (pendant son traitement) sur notre DiskFileItemFactory.

Enfin, nous allons créer un objet ServletFileUpload qui représentera le fichier lui-même . Il exposera le contenu du téléchargement en plusieurs parties pour le côté serveur de persistance finale:

if (ServletFileUpload.isMultipartContent(request)) { DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(MEMORY_THRESHOLD); factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); ServletFileUpload upload = new ServletFileUpload(factory); upload.setFileSizeMax(MAX_FILE_SIZE); upload.setSizeMax(MAX_REQUEST_SIZE); String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); } //... }

Et, ensuite, nous pouvons extraire ces contenus et les écrire sur le disque:

if (ServletFileUpload.isMultipartContent(request)) { //... List formItems = upload.parseRequest(request); if (formItems != null && formItems.size() > 0) { for (FileItem item : formItems) { if (!item.isFormField()) { String fileName = new File(item.getName()).getName(); String filePath = uploadPath + File.separator + fileName; File storeFile = new File(filePath); item.write(storeFile); request.setAttribute("message", "File " + fileName + " has uploaded successfully!"); } } } }

4. Exécution de l'exemple

Après avoir compilé notre projet dans un fichier .war , nous pouvons le déposer dans notre instance Tomcat locale et le démarrer.

À partir de là, nous pouvons afficher la vue de téléchargement principale où nous sommes présentés avec un formulaire:

Après avoir téléchargé avec succès notre fichier, nous devrions voir le message:

Enfin, nous pouvons vérifier l'emplacement spécifié dans notre servlet:

5. Conclusion

C'est ça! Nous avons appris comment fournir des téléchargements de fichiers en plusieurs parties à l'aide de Jakarta EE, ainsi que de la bibliothèque Common FileUpload d' Apache !

Des extraits de code, comme toujours, peuvent être trouvés sur GitHub.