Bestand uploaden met Spring MVC

1. Overzicht

In eerdere artikelen hebben we de basisprincipes van formulierafhandeling geïntroduceerd en de formuliertagbibliotheek in Spring MVC verkend.

In dit artikel concentreren we ons op wat Spring te bieden heeft multipart (bestandsupload) ondersteuning in webapplicaties.

Met de lente kunnen we deze meerdelige ondersteuning met pluggable inschakelen MultipartResolver voorwerpen. Het raamwerk biedt er een MultipartResolver implementatie voor gebruik met Commons FileUpload en een ander voor gebruik met Servlet 3.0 multipart request parsing.

Na het configureren van het MultipartResolver we zullen zien hoe je een enkel bestand en meerdere bestanden uploadt.

We zullen het ook bespreken Spring Boot.

2. Commons FileUpload

Gebruiken CommonsMultipartResolver om het uploaden van bestanden af ​​te handelen, moeten we de volgende afhankelijkheid toevoegen:

 commons-fileupload commons-fileupload 1.3.1 

Nu kunnen we de CommonsMultipartResolver bean in onze Spring-configuratie.

Dit MultipartResolver wordt geleverd met een reeks van set methode om eigenschappen te definiëren, zoals de maximale grootte voor uploads:

@Bean (name = "multipartResolver") openbare CommonsMultipartResolver multipartResolver () {CommonsMultipartResolver multipartResolver = nieuwe CommonsMultipartResolver (); multipartResolver.setMaxUploadSize (100000); retourneer multipartResolver; }

Hier moeten we verschillende eigenschappen van controleren CommonsMultipartResolver in de Bean-definitie zelf.

3. Met Servlet 3.0

Om te kunnen gebruiken Servlet 3.0 multipart parsing, we moeten een paar delen van de applicatie configureren. Eerst moeten we een MultipartConfigElement in onze DispatcherServletregistratie:

openbare klasse MainWebAppInitializer implementeert WebApplicationInitializer {private String TMP_FOLDER = "/ tmp"; privé int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; @Override public void onStartup (ServletContext sc) gooit ServletException {ServletRegistration.Dynamic appServlet = sc.addServlet ("mvc", nieuwe DispatcherServlet (nieuwe GenericWebApplicationContext ())); appServlet.setLoadOnStartup (1); MultipartConfigElement multipartConfigElement = nieuw MultipartConfigElement (TMP_FOLDER, MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2); appServlet.setMultipartConfig (multipartConfigElement); }}

In de MultipartConfigElement object, hebben we de opslaglocatie, maximale individuele bestandsgrootte, maximale aanvraaggrootte (in het geval van meerdere bestanden in één aanvraag) en de grootte waarmee de voortgang van het uploaden van bestanden naar de opslaglocatie wordt doorgespoeld, geconfigureerd.

Deze instellingen moeten worden toegepast op het registratieniveau van de servlet, zoals Servlet 3.0 staat niet toe dat ze worden geregistreerd in het MultipartResolver zoals het geval is met CommonsMultipartResolver.

Zodra dit is gebeurd, we kunnen de StandardServletMultipartResolver naar onze Spring-configuratie:

@Bean openbare StandardServletMultipartResolver multipartResolver () {retourneer nieuwe StandardServletMultipartResolver (); }

4. Een bestand uploaden

Om ons bestand te uploaden, kunnen we een eenvoudig formulier bouwen waarin we een HTML gebruiken invoer tag met type = 'bestand'.

Ongeacht de configuratie van de uploadverwerking die we hebben gekozen, moeten we het coderingskenmerk van het formulier instellen op multipart / form-data. Hierdoor weet de browser hoe het formulier moet worden gecodeerd:

Selecteer een bestand om te uploaden

Om het geüploade bestand op te slaan, kunnen we een MultipartFile variabele. We kunnen deze variabele ophalen uit de request-parameter binnen de methode van onze controller:

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

De MultipartFile class geeft toegang tot details over het geüploade bestand, inclusief bestandsnaam, bestandstype, enzovoort. We kunnen een eenvoudige HTML-pagina gebruiken om deze informatie weer te geven:

Ingediend bestand

Oorspronkelijke bestandsnaam:$ {file.originalFilename}
Type:$ {file.contentType}

5. Uploaden Meerdere bestanden

Om meerdere bestanden in één verzoek te uploaden, plaatsen we eenvoudig meerdere invoerbestandsvelden in het formulier:

Selecteer een bestand om te uploaden
Selecteer een bestand om te uploaden
Selecteer een bestand om te uploaden

We moeten ervoor zorgen dat elk invoerveld dezelfde naam heeft, zodat het toegankelijk is als een array van MultipartFile:

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

Nu kunnen we eenvoudig die array herhalen om bestandsinformatie weer te geven:

   Spring MVC-bestand uploaden 

Ingediende bestanden

Oorspronkelijke bestandsnaam:$ {file.originalFilename}
Type:$ {file.contentType}

6. Bestanden met aanvullende formuliergegevens uploaden

We kunnen ook aanvullende informatie naar de server sturen, samen met het bestand dat wordt geüpload. We hoeven alleen de verplichte velden in het formulier op te nemen:

Naam
E-mail
Selecteer een bestand om te uploaden

In de controller kunnen we alle formuliergegevens ophalen met behulp van de @RequestParam annotatie:

@PostMapping ("/ uploadFileWithAddtionalData") public String indienen (@RequestParam MultipartFile-bestand, @RequestParam Stringnaam, @RequestParam String-e-mail, ModelMap modelMap) {modelMap.addAttribute ("naam", naam); modelMap.addAttribute ("e-mail", e-mail); modelMap.addAttribute ("bestand", bestand); retourneer "fileUploadView"; }

Net als bij eerdere secties, kunnen we de HTML-pagina gebruiken met JSTL tags om de informatie weer te geven.

We kunnen ook alle formuliervelden in een modelklasse inkapselen en gebruiken @ModelAttribute annotatie in de controller. Dit zou handig zijn als er naast het bestand veel extra velden zijn. Laten we eens kijken naar de code:

openbare klasse FormDataWithFile {private String-naam; privé String-e-mail; privé MultipartFile-bestand; // standaard getters en setters}
@PostMapping ("/ uploadFileModelAttribute") openbare String indienen (@ModelAttribute FormDataWithFile formDataWithFile, ModelMap modelMap) {modelMap.addAttribute ("formDataWithFile", formDataWithFile); retourneer "fileUploadView"; }

7. Spring Boot File Upload

Als we Spring Boot gebruiken, is alles wat we tot nu toe hebben gezien nog steeds van toepassing.

Spring Boot maakt het echter nog eenvoudiger om alles met weinig gedoe te configureren en te starten.

Vooral, het is niet nodig om een ​​servlet te configureren, aangezien Boot het voor ons registreert en configureert, op voorwaarde dat we de webmodule opnemen in onze afhankelijkheden:

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

We kunnen de laatste versie van spring-boot-starter-web op Maven Central.

Als we de maximale bestandsuploadgrootte willen bepalen, kunnen we onze application.properties:

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

We kunnen ook bepalen of het uploaden van bestanden is ingeschakeld, en de locatie voor het uploaden van bestanden:

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

Merk op dat we hebben gebruikt $ {java.io.tmpdir} om de uploadlocatie te definiëren zodat we de tijdelijke locatie kunnen gebruiken voor verschillende besturingssystemen.

8. Conclusie

In dit artikel hebben we gekeken naar verschillende manieren om meervoudige ondersteuning in het voorjaar te configureren. Hiermee kunnen we bestandsuploads in onze webapplicaties ondersteunen.

De implementatie van deze tutorial is te vinden in een GitHub-project. Wanneer het project lokaal wordt uitgevoerd, kan het formuliervoorbeeld worden geopend op // localhost: 8080 / spring-mvc-java / fileUpload