Bestanden uploaden met Servlets en JSP

1. Inleiding

In deze korte tutorial zullen we zien hoe je een bestand uploadt vanuit een servlet.

Om dit te bereiken, zullen we eerst de vanille Jakarta EE-oplossing zien met mogelijkheden voor het uploaden van bestanden door native @MultipartConfig annotatie.

Dan gaan we over de Apache Commons Bestand upload bibliotheek, voor eerdere versies van de Servlet API.

2. Met behulp van Jakarta EE @MultipartConfig

Jakarta EE heeft de mogelijkheid om direct uit de verpakking meerdelige uploads te ondersteunen.

Als zodanig is het waarschijnlijk een standaardoptie bij het verrijken van een Jakarta EE-app met ondersteuning voor het uploaden van bestanden.

Laten we eerst een formulier aan ons HTML-bestand toevoegen:

 Kies een bestand: 

Het formulier moet worden gedefinieerd met behulp van de enctype = "multipart / form-data" attribuut om een ​​upload uit meerdere delen aan te geven.

De volgende, we willen onze HttpServlet met de juiste informatie met behulp van de @MultipartConfig annotatie:

@MultipartConfig (fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5) openbare klasse MultipartServlet breidt HttpServlet {// ...} 

Laten we er dan voor zorgen dat onze standaard uploadmap voor de server is ingesteld:

String uploadPath = getServletContext (). GetRealPath ("") + File.separator + UPLOAD_DIRECTORY; Bestand uploadDir = nieuw bestand (uploadPath); if (! uploadDir.exists ()) uploadDir.mkdir (); 

Tenslotte, we kunnen onze inbound gemakkelijk terugvinden het dossier van de verzoek de ... gebruiken getParts () methode, en sla het op de schijf op:

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

Merk op dat we in dit voorbeeld een hulpmethode getFileName () gebruiken:

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

Voor Servlet 3.1. projecten, kunnen we als alternatief de Part.getSubmittedFileName () methode:

fileName = part.getSubmittedFileName ();

3. Apache Commons FileUpload gebruiken

Als we geen Servlet 3.0-project hebben, kunnen we de Apache Commons FileUpload-bibliotheek rechtstreeks gebruiken.

3.1. Opstelling

We willen het volgende gebruiken pom.xml afhankelijkheden om ons voorbeeld te laten draaien:

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

De meest recente versies zijn te vinden door snel te zoeken in Maven's Central Repository: commons-fileupload en commons-io.

3.2. Upload Servlet

De drie belangrijkste onderdelen om Apache's te integreren Bestand upload bibliotheek gaat als volgt:

  • Een uploadformulier in een .jsp bladzijde.
  • Configureer je DiskFileItemFactory en ServletFileUpload voorwerp.
  • Verwerking van de feitelijke inhoud van een upload van een meerdelig bestand.

Het uploadformulier is hetzelfde als dat in de vorige sectie.

Laten we verder gaan met het maken van onze Jakarta EE-servlet.

In onze verzoekverwerkingsmethode kunnen we de inkomende verpakken HttpRequest met een vinkje om te zien of het een upload uit meerdere delen is.

We zullen ook specificeren welke bronnen moeten worden toegewezen aan de bestandsupload tijdelijk (terwijl deze wordt verwerkt) op onze DiskFileItemFactory.

Ten slotte, we maken een ServletFileUpload object dat het daadwerkelijke bestand zelf zal vertegenwoordigen. Het toont de inhoud van de meerdelige upload voor de uiteindelijke persistentie aan de serverzijde:

if (ServletFileUpload.isMultipartContent (verzoek)) {DiskFileItemFactory factory = nieuwe DiskFileItemFactory (); factory.setSizeThreshold (MEMORY_THRESHOLD); factory.setRepository (nieuw bestand (System.getProperty ("java.io.tmpdir"))); ServletFileUpload upload = nieuwe ServletFileUpload (fabriek); upload.setFileSizeMax (MAX_FILE_SIZE); upload.setSizeMax (MAX_REQUEST_SIZE); String uploadPath = getServletContext (). GetRealPath ("") + File.separator + UPLOAD_DIRECTORY; Bestand uploadDir = nieuw bestand (uploadPath); if (! uploadDir.exists ()) {uploadDir.mkdir (); } // ...}

En dan kunnen we die inhoud extraheren en naar schijf schrijven:

if (ServletFileUpload.isMultipartContent (request)) {// ... List formItems = upload.parseRequest (request); if (formItems! = null && formItems.size ()> 0) {for (FileItem item: formItems) {if (! item.isFormField ()) {String fileName = nieuw bestand (item.getName ()). getName () ; String filePath = uploadPath + File.separator + bestandsnaam; Bestand storeFile = nieuw bestand (filePath); item.write (storeFile); request.setAttribute ("bericht", "Bestand" + bestandsnaam + "is geüpload!"); }}}}

4. Het voorbeeld uitvoeren

Nadat we ons project hebben gecompileerd in een .oorlog, kunnen we het in onze lokale Tomcat-instantie plaatsen en opstarten.

Van daaruit kunnen we de hoofdweergave voor uploaden openen, waar we een formulier te zien krijgen:

Na het succesvol uploaden van ons bestand, zouden we het bericht moeten zien:

Ten slotte kunnen we de locatie controleren die is opgegeven in onze servlet:

5. Conclusie

Dat is het! We hebben geleerd hoe we bestandsuploads uit meerdere delen kunnen bieden met Jakarta EE, evenals Apache's Common Bestand upload bibliotheek!

Codefragmenten zijn, zoals altijd, te vinden op GitHub.