Caricamento di file con servlet e JSP

1. Introduzione

In questo rapido tutorial, vedremo come caricare un file da un servlet.

Per ottenere ciò, vedremo prima la soluzione vanilla Jakarta EE con funzionalità di caricamento file fornite dall'annotazione nativa @MultipartConfig .

Quindi, esamineremo la libreria FileUpload di Apache Commons , per le versioni precedenti dell'API Servlet.

2. Utilizzo di Jakarta EE @MultipartConfig

Jakarta EE ha la capacità di supportare caricamenti in più parti immediatamente.

In quanto tale, è probabilmente un punto di riferimento predefinito quando si arricchisce un'app Jakarta EE con il supporto per il caricamento di file.

Innanzitutto, aggiungiamo un modulo al nostro file HTML:

 Choose a file:   

Il modulo deve essere definito utilizzando l' attributo enctype = "multipart / form-data" per segnalare un caricamento in più parti.

Successivamente, vorremo annotare il nostro HttpServlet con le informazioni corrette utilizzando l' annotazione @MultipartConfig :

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

Quindi, assicuriamoci che la nostra cartella di caricamento del server predefinita sia impostata:

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

Infine, possiamo facilmente recuperare il nostro file in entrata dalla richiesta utilizzando il metodo getParts () e salvarlo sul disco:

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

Nota che, in questo esempio, stiamo usando un metodo di supporto 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; }

Per Servlet 3.1. progetti, potremmo in alternativa utilizzare il metodo Part.getSubmittedFileName () :

fileName = part.getSubmittedFileName();

3. Utilizzo di Apache Commons FileUpload

Se non siamo su un progetto Servlet 3.0, possiamo utilizzare direttamente la libreria FileUpload di Apache Commons.

3.1. Impostare

Vorremo utilizzare le seguenti dipendenze pom.xml per far funzionare il nostro esempio:

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

Le versioni più recenti possono essere trovate con una rapida ricerca nel Repository centrale di Maven: commons-fileupload e commons-io.

3.2. Carica Servlet

Le tre parti principali per incorporare la libreria FileUpload di Apache sono le seguenti:

  • Un modulo di caricamento in una pagina .jsp .
  • Configurazione dell'oggetto DiskFileItemFactory e ServletFileUpload .
  • Elaborazione del contenuto effettivo di un caricamento di file in più parti.

Il modulo di caricamento è lo stesso di quello nella sezione precedente.

Passiamo alla creazione del nostro servlet Jakarta EE.

Nel nostro metodo di elaborazione delle richieste, possiamo racchiudere l' HttpRequest in arrivo con un controllo per vedere se si tratta di un caricamento in più parti.

Specificheremo anche quali risorse allocare temporaneamente al caricamento del file (durante l'elaborazione) sul nostro DiskFileItemFactory.

Infine, creeremo un oggetto ServletFileUpload che rappresenterà il file stesso . Esporrà il contenuto del caricamento in più parti per la persistenza finale lato server:

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(); } //... }

E poi possiamo estrarre quei contenuti e scriverli su disco:

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. Esecuzione dell'esempio

Dopo aver compilato il nostro progetto in un .war , possiamo rilasciarlo nella nostra istanza Tomcat locale e avviarlo.

Da lì, possiamo visualizzare la visualizzazione di caricamento principale in cui ci viene presentato un modulo:

Dopo aver caricato con successo il nostro file, dovremmo vedere il messaggio:

Infine, possiamo controllare la posizione specificata nel nostro servlet:

5. conclusione

Questo è tutto! Abbiamo imparato come fornire caricamenti di file in più parti utilizzando Jakarta EE, così come la libreria Common FileUpload di Apache !

Gli snippet di codice, come sempre, possono essere trovati su GitHub.