Spring en Apache FileUpload

1. Overzicht

De Apache Commons-bestandsuploadbibliotheek helpt ons grote bestanden te uploaden via het HTTP-protocol met behulp van de multipart / form-data inhoudstype.

In deze korte tutorial gaan we bekijken hoe we het met Spring kunnen integreren.

2. Maven afhankelijkheden

Om de bibliotheek te gebruiken, hebben we de commons-bestandupload artefact:

 commons-fileupload commons-fileupload 1.3.3 

De nieuwste versie is te vinden op Maven Central.

3. Alles tegelijk overdragen

Voor demonstratiedoeleinden gaan we een Controller verzoeken verwerken met een bestandspayload:

@PostMapping ("/ upload") public String handleUpload (verzoek HttpServletRequest) genereert uitzondering {boolean isMultipart = ServletFileUpload.isMultipartContent (verzoek); DiskFileItemFactory factory = nieuwe DiskFileItemFactory (); factory.setRepository (nieuw bestand (System.getProperty ("java.io.tmpdir"))); factory.setSizeThreshold (DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD); factory.setFileCleaningTracker (null); ServletFileUpload upload = nieuwe ServletFileUpload (fabriek); Lijstitems = upload.parseRequest (verzoek); Iterator iter = items.iterator (); while (iter.hasNext ()) {FileItem item = iter.next (); if (! item.isFormField ()) {probeer (InputStream uploadStream = item.getInputStream (); OutputStream out = nieuwe FileOutputStream ("file.mov");) {IOUtils.copy (geüploadeStream, uit); }}} retourneer "succes!"; } 

In het begin, we moeten controleren of het verzoek uit meerdere delen bestaat de ... gebruiken isMultipartContent methode gevonden in de ServletFileUpload klas uit de bibliotheek.

Standaard, Lente heeft een MultipartResolverdie we moeten uitschakelen om deze bibliotheek te gebruiken. Anders leest het de inhoud van het verzoek voordat het ons bereikt Controller.

Dit kunnen we bereiken door deze configuratie op te nemen in ons application.properties het dossier:

spring.http.multipart.enabled = false

Nu kunnen we de map instellen waar onze bestanden zullen worden opgeslagen, de drempel waarin de bibliotheek besluit om naar schijf te schrijven en of bestanden moeten worden verwijderd nadat het verzoek is beëindigd.

De bibliotheek biedt een DiskFileItemFactory klasse datneemt de verantwoordelijkheid voor de configuratie voor het opslaan en opschonen van bestanden. De setRepository methode stelt de doeldirectory in, waarbij de standaard wordt getoond in het voorbeeld.

Vervolgens de setSizeThreshold stelt een maximale bestandsgrootte in.

Dan hebben we de setFileCleaningTracker methode die, indien ingesteld op null, de tijdelijke bestanden onaangeroerd laat. Standaard worden ze verwijderd nadat het verzoek is voltooid.

Nu kunnen we doorgaan met de daadwerkelijke bestandsafhandeling.

Eerst creëren we onze ServletFileUpload door onze eerder opgerichte fabriek op te nemen; vervolgens gaan we verder met het parseren van het verzoek en het genereren van een lijst met FileItem die zijn de belangrijkste abstractie van de bibliotheek voor de formuliervelden.

Als we nu weten dat het geen normaal formulierveld is, gaan we verder met het extraheren van het InputStream en om de handige kopieermethode aan te roepen van IOUtils (voor meer opties kunt u deze tutorial bekijken).

Nu hebben we ons bestand opgeslagen in de benodigde map. Dit is meestal een gemakkelijkere manier om met deze situatie om te gaan, omdat het gemakkelijk toegang geeft tot de bestanden, maar ook de tijd / geheugenefficiëntie is niet optimaal.

In de volgende sectie gaan we de streaming-API bekijken.

4. Streaming-API

De streaming-API is gebruiksvriendelijk, waardoor het een geweldige manier is om grote bestanden te verwerken door simpelweg niet naar een tijdelijke locatie te kopiëren:

ServletFileUpload upload = nieuwe ServletFileUpload (); FileItemIterator iterStream = upload.getItemIterator (verzoek); while (iterStream.hasNext ()) {FileItemStream item = iterStream.next (); Tekenreeksnaam = item.getFieldName (); InputStream stream = item.openStream (); if (! item.isFormField ()) {// Verwerk de InputStream} else {String formFieldValue = Streams.asString (stream); }} 

We kunnen in het vorige codefragment zien dat we niet langer een DiskFileItemFactory. Dit is zo omdat, bij gebruik van de streaming-API hebben we deze niet nodig.

Naast het verwerken van velden biedt de bibliotheek een FileItemIterator, die niets leest totdat we ze uit het verzoek halen met de De volgende methode.

Ten slotte kunnen we zien hoe we de waarden van de andere formuliervelden kunnen verkrijgen.

5. Conclusie

In dit artikel hebben we besproken hoe we de Apache Commons File Upload Library met Spring kunnen gebruiken om grote bestanden te uploaden en te verwerken.

Zoals altijd is de volledige broncode te vinden op GitHub.