1. Información general
En artículos anteriores, presentamos los conceptos básicos del manejo de formularios y exploramos la biblioteca de etiquetas de formulario en Spring MVC.
En este artículo, nos centramos en lo que ofrece Spring para la compatibilidad con varias partes (carga de archivos) en aplicaciones web.
Spring nos permite habilitar este soporte multiparte con objetos MultipartResolver conectables . El marco proporciona una implementación de MultipartResolver para usar con Commons FileUpload y otra para usar con el análisis de solicitudes de varias partes de Servlet 3.0 .
Después de configurar MultipartResolver veremos cómo cargar un solo archivo y varios archivos.
También tocaremos Spring Boot.
2. Commons FileUpload
Para usar CommonsMultipartResolver para manejar la carga del archivo, necesitamos agregar la siguiente dependencia:
commons-fileupload commons-fileupload 1.3.1
Ahora podemos definir el bean CommonsMultipartResolver en nuestra configuración de Spring.
Este MultipartResolver viene con una serie de métodos establecidos para definir propiedades como el tamaño máximo para cargas:
@Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(100000); return multipartResolver; }
Aquí necesitamos controlar diferentes propiedades de CommonsMultipartResolver en la propia definición de Bean.
3. Con Servlet 3.0
Para utilizar el análisis multiparte de Servlet 3.0 , necesitamos configurar un par de piezas de la aplicación. Primero, necesitamos establecer un MultipartConfigElement en nuestro registro 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); } }
En el objeto MultipartConfigElement , hemos configurado la ubicación de almacenamiento, el tamaño máximo de archivo individual, el tamaño máximo de solicitud (en el caso de varios archivos en una sola solicitud) y el tamaño en el que el progreso de carga del archivo se descarga en la ubicación de almacenamiento.
Esta configuración debe aplicarse en el nivel de registro de servlet, ya que Servlet 3.0 no permite que se registren en MultipartResolver como es el caso de CommonsMultipartResolver.
Una vez hecho esto, podemos agregar StandardServletMultipartResolver a nuestra configuración de Spring:
@Bean public StandardServletMultipartResolver multipartResolver() { return new StandardServletMultipartResolver(); }
4. Carga de un archivo
Para cargar nuestro archivo, podemos construir un formulario simple en el que usamos una etiqueta de entrada HTML con type = 'file'.
Independientemente de la configuración de manejo de carga que hemos elegido, debemos establecer el atributo de codificación del formulario en multipart / form-data. Esto le permite al navegador saber cómo codificar el formulario:
Select a file to upload
Para almacenar el archivo cargado podemos usar una variable MultipartFile . Podemos recuperar esta variable del parámetro de solicitud dentro del método de nuestro controlador:
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST) public String submit(@RequestParam("file") MultipartFile file, ModelMap modelMap) { modelMap.addAttribute("file", file); return "fileUploadView"; }
La clase MultipartFile proporciona acceso a detalles sobre el archivo cargado , incluido el nombre del archivo, el tipo de archivo, etc. Podemos usar una página HTML simple para mostrar esta información:
Submitted File
OriginalFileName:
${file.originalFilename}
Type:
${file.contentType}
5. Carga de varios archivos
Para cargar varios archivos en una sola solicitud, simplemente colocamos varios campos de archivo de entrada dentro del formulario:
Select a file to upload
Select a file to upload
Select a file to upload
Debemos tener cuidado de que cada campo de entrada tenga el mismo nombre para que se pueda acceder a él como una matriz de MultipartFile :
@RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST) public String submit(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) { modelMap.addAttribute("files", files); return "fileUploadView"; }
Ahora, podemos simplemente iterar sobre esa matriz para mostrar la información de los archivos:
Spring MVC File Upload Submitted Files
OriginalFileName:
${file.originalFilename}
Type:
${file.contentType}
6. Carga de archivos con datos de formulario adicionales
También podemos enviar información adicional al servidor junto con el archivo que se está cargando. Solo tenemos que incluir los campos obligatorios en el formulario:
Name
Email
Select a file to upload
En el controlador, podemos obtener todos los datos del formulario usando la anotación @RequestParam :
@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"; }
Al igual que en las secciones anteriores, podemos usar la página HTML con etiquetas JSTL para mostrar la información.
También podemos encapsular todos los campos de formulario en una clase de modelo y usar la anotación @ModelAttribute en el controlador. Esto sería útil cuando hay muchos campos adicionales junto con el archivo. Veamos el código:
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. Carga de archivos de Spring Boot
Si usamos Spring Boot, todo lo que hemos visto hasta ahora se aplica.
Sin embargo, Spring Boot hace que sea aún más fácil configurar e iniciar todo sin problemas.
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
En este artículo, analizamos diferentes formas de configurar el soporte multiparte en Spring. Con estos, podemos admitir la carga de archivos en nuestras aplicaciones web.
La implementación de este tutorial se puede encontrar en un proyecto de GitHub. Cuando el proyecto se ejecuta localmente, se puede acceder al ejemplo de formulario en // localhost: 8080 / spring-mvc-java / fileUpload