Carga de archivos con servlets y JSP

1. Introducción

En este tutorial rápido, veremos cómo cargar un archivo desde un servlet.

Para lograr esto, primero veremos la solución vanilla Jakarta EE con capacidades de carga de archivos proporcionadas por la anotación nativa @MultipartConfig .

Luego, repasaremos la biblioteca Apache Commons FileUpload , para versiones anteriores de la API de Servlet.

2. Uso de Jakarta EE @MultipartConfig

Jakarta EE tiene la capacidad de admitir cargas de varias partes listas para usar.

Como tal, probablemente sea una opción predeterminada al enriquecer una aplicación Jakarta EE con soporte para carga de archivos.

Primero, agreguemos un formulario a nuestro archivo HTML:

 Choose a file:   

El formulario debe definirse utilizando el atributo enctype = ”multipart / form-data” para señalar una carga multiparte.

A continuación, queremos anotar nuestro HttpServlet con la información correcta usando la anotación @MultipartConfig :

@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5) public class MultipartServlet extends HttpServlet { //... } 

Luego, asegurémonos de que nuestra carpeta de carga del servidor predeterminada esté configurada:

String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; File uploadDir = new File(uploadPath); if (!uploadDir.exists()) uploadDir.mkdir(); 

Finalmente, podemos recuperar fácilmente nuestro Archivo entrante de la solicitud usando el método getParts () y guardarlo en el disco:

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

Tenga en cuenta que, en este ejemplo, estamos usando un método auxiliar getFileName ():

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

Para Servlet 3.1. proyectos, podríamos usar alternativamente el método Part.getSubmittedFileName () :

fileName = part.getSubmittedFileName();

3. Uso de Apache Commons FileUpload

Si no estamos en un proyecto de Servlet 3.0, podemos usar la biblioteca Apache Commons FileUpload directamente.

3.1. Preparar

Queremos utilizar las siguientes dependencias pom.xml para ejecutar nuestro ejemplo:

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

Las versiones más recientes se pueden encontrar con una búsqueda rápida en el repositorio central de Maven: commons-fileupload y commons-io.

3.2. Subir servlet

Las tres partes principales para incorporar la biblioteca FileUpload de Apache son las siguientes:

  • Un formulario de carga en una página .jsp .
  • Configuración de su objeto DiskFileItemFactory y ServletFileUpload .
  • Procesamiento del contenido real de la carga de un archivo de varias partes.

El formulario de carga es el mismo que el de la sección anterior.

Pasemos a la creación de nuestro servlet Jakarta EE.

En nuestro método de procesamiento de solicitudes, podemos envolver la HttpRequest entrante con una verificación para ver si es una carga de varias partes.

También especificaremos qué recursos asignar a la carga del archivo temporalmente (mientras se procesa) en nuestro DiskFileItemFactory.

Por último, crearemos un objeto ServletFileUpload que representará el archivo real en sí . Expondrá el contenido de la carga de varias partes para el lado del servidor de persistencia final:

if (ServletFileUpload.isMultipartContent(request)) { DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(MEMORY_THRESHOLD); factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); ServletFileUpload upload = new ServletFileUpload(factory); upload.setFileSizeMax(MAX_FILE_SIZE); upload.setSizeMax(MAX_REQUEST_SIZE); String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); } //... }

Y luego podemos extraer esos contenidos y escribirlos en el disco:

if (ServletFileUpload.isMultipartContent(request)) { //... List formItems = upload.parseRequest(request); if (formItems != null && formItems.size() > 0) { for (FileItem item : formItems) { if (!item.isFormField()) { String fileName = new File(item.getName()).getName(); String filePath = uploadPath + File.separator + fileName; File storeFile = new File(filePath); item.write(storeFile); request.setAttribute("message", "File " + fileName + " has uploaded successfully!"); } } } }

4. Ejecución del ejemplo

Una vez que hayamos compilado nuestro proyecto en un .war , podemos colocarlo en nuestra instancia local de Tomcat e iniciarlo.

Desde allí, podemos abrir la vista de carga principal donde se nos presenta un formulario:

Después de cargar con éxito nuestro archivo, deberíamos ver el mensaje:

Por último, podemos verificar la ubicación especificada en nuestro servlet:

5. Conclusión

¡Eso es! ¡Hemos aprendido cómo proporcionar cargas de archivos de varias partes utilizando Jakarta EE, así como la biblioteca Common FileUpload de Apache !

Los fragmentos de código, como siempre, se pueden encontrar en GitHub.