Caricamento di file con Spring MVC

1. Panoramica

Negli articoli precedenti, abbiamo introdotto le basi della gestione dei moduli ed esplorato la libreria di tag del modulo in Spring MVC.

In questo articolo, ci concentreremo su ciò che Spring offre per il supporto multipart (caricamento di file) nelle applicazioni web.

Spring ci consente di abilitare questo supporto multiparte con oggetti MultipartResolver collegabili . Il framework fornisce un'implementazione MultipartResolver da utilizzare con Commons FileUpload e un'altra da utilizzare con l' analisi delle richieste multipart Servlet 3.0 .

Dopo aver configurato il MultipartResolver vedremo come caricare un singolo file e più file.

Toccheremo anche lo Spring Boot.

2. Commons FileUpload

Per utilizzare CommonsMultipartResolver per gestire il caricamento del file, dobbiamo aggiungere la seguente dipendenza:

 commons-fileupload commons-fileupload 1.3.1 

Ora possiamo definire il bean CommonsMultipartResolver nella nostra configurazione Spring.

Questo MultipartResolver viene fornito con una serie di metodi set per definire proprietà come la dimensione massima per i caricamenti:

@Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(100000); return multipartResolver; }

Qui dobbiamo controllare diverse proprietà di CommonsMultipartResolver nella definizione Bean stessa.

3. Con Servlet 3.0

Per poter utilizzare l' analisi multiparte Servlet 3.0 , è necessario configurare un paio di parti dell'applicazione. Innanzitutto, dobbiamo impostare un MultipartConfigElement nella nostra registrazione DispatcherServlet :

public class MainWebAppInitializer implements WebApplicationInitializer { private String TMP_FOLDER = "/tmp"; private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; @Override public void onStartup(ServletContext sc) throws ServletException { ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet( new GenericWebApplicationContext())); appServlet.setLoadOnStartup(1); MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2); appServlet.setMultipartConfig(multipartConfigElement); } }

Nel MultipartConfigElement oggetto, abbiamo configurato la posizione di archiviazione, dimensione massima del file individuale, la dimensione richiesta massima (nel caso di più file in una singola richiesta), e la dimensione in cui l'avanzamento del caricamento di file viene scaricato alla posizione di archiviazione.

Queste impostazioni devono essere applicate a livello di registrazione servlet, poiché Servlet 3.0 non consente di registrarle in MultipartResolver come nel caso di CommonsMultipartResolver.

Fatto ciò, possiamo aggiungere StandardServletMultipartResolver alla nostra configurazione Spring:

@Bean public StandardServletMultipartResolver multipartResolver() { return new StandardServletMultipartResolver(); }

4. Caricamento di un file

Per caricare il nostro file, possiamo costruire un semplice form in cui usiamo un tag di input HTML con type = 'file'.

Indipendentemente dalla configurazione della gestione del caricamento, abbiamo scelto, dobbiamo impostare l'attributo di codifica del modulo su multipart / form-data. Ciò consente al browser di sapere come codificare il modulo:


    
Select a file to upload

Per memorizzare il file caricato possiamo utilizzare una variabile MultipartFile . Possiamo recuperare questa variabile dal parametro di richiesta all'interno del metodo del nostro controller:

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

La classe MultipartFile fornisce l'accesso ai dettagli sul file caricato , inclusi il nome del file, il tipo di file e così via. Possiamo utilizzare una semplice pagina HTML per visualizzare queste informazioni:

Submitted File

OriginalFileName: ${file.originalFilename}
Type: ${file.contentType}

5. Caricamento di più file

Per caricare più file in una singola richiesta, inseriamo semplicemente più campi di file di input all'interno del modulo:


    
Select a file to upload
Select a file to upload
Select a file to upload

Dobbiamo fare attenzione che ogni campo di input abbia lo stesso nome in modo che sia possibile accedervi come un array di MultipartFile :

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

Ora possiamo semplicemente iterare su quell'array per visualizzare le informazioni sui file:

   Spring MVC File Upload   

Submitted Files

OriginalFileName: ${file.originalFilename}
Type: ${file.contentType}

6. Caricamento di file con dati del modulo aggiuntivi

Possiamo anche inviare ulteriori informazioni al server insieme al file da caricare. Non ci resta che includere i campi obbligatori nel modulo:


    
Name
Email
Select a file to upload

In the controller, we can get all the form data using the @RequestParam annotation:

@PostMapping("/uploadFileWithAddtionalData") public String submit( @RequestParam MultipartFile file, @RequestParam String name, @RequestParam String email, ModelMap modelMap) { modelMap.addAttribute("name", name); modelMap.addAttribute("email", email); modelMap.addAttribute("file", file); return "fileUploadView"; }

Similar to previous sections, we can use the HTML page with JSTL tags to display the information.

We can also encapsulate all the form fields in a model class and use @ModelAttribute annotation in the controller. This would be helpful when there's a lot of additional fields along with the file. Let' look at the code:

public class FormDataWithFile { private String name; private String email; private MultipartFile file; // standard getters and setters }
@PostMapping("/uploadFileModelAttribute") public String submit(@ModelAttribute FormDataWithFile formDataWithFile, ModelMap modelMap) { modelMap.addAttribute("formDataWithFile", formDataWithFile); return "fileUploadView"; }

7. Spring Boot File Upload

If we're using Spring Boot, everything we've seen so far still applies.

However, Spring Boot makes it even easier to configure and start everything with little hassle.

In particular, it's not necessary to configure any servlet, as Boot will register and configure it for us, provided that we include the web module in our dependencies:

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

We can find the latest version of spring-boot-starter-web on Maven Central.

If we want to control the maximum file upload size, we can edit our application.properties:

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

We can also control whether file uploading is enabled, and the location for file upload:

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

Note that we've used ${java.io.tmpdir} to define the upload location so that we can use the temporary location for different operating systems.

8. Conclusion

In questo articolo, abbiamo esaminato diversi modi per configurare il supporto multiparte in primavera. Usandoli, possiamo supportare il caricamento di file nelle nostre applicazioni web.

L'implementazione di questo tutorial può essere trovata in un progetto GitHub. Quando il progetto viene eseguito localmente, è possibile accedere al modulo di esempio in // localhost: 8080 / spring-mvc-java / fileUpload