comment
IRC Chat
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

Subir archivos con Servlet

  • 2 Respuestas
  • 3593 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Gus Garsaky

  • *
  • Underc0der
  • Mensajes: 93
  • Actividad:
    0%
  • Reputación -1
    • Ver Perfil
  • Skype: gus.garsaky
« en: Julio 05, 2015, 06:15:56 pm »
Subir archivos en Java es realmente muy sencillo. Ya Java nos provee interfaces como Part para facilitarnos el trabajo. Veamos un ejemplo:

Vamos con nuestro sencillo formulario:


Código: HTML5
  1. <You are not allowed to view links. Register or Login>Subir archivos</You are not allowed to view links. Register or Login>
  2.     <You are not allowed to view links. Register or Login method="post" action="upload" enctype="multipart/form-data">
  3.     <You are not allowed to view links. Register or Login>
  4.         <You are not allowed to view links. Register or Login>Formulario de subida</You are not allowed to view links. Register or Login>
  5.         <You are not allowed to view links. Register or Login type="file" name="files" id="files" multiple/>
  6.         <You are not allowed to view links. Register or Login type="submit">Subir</You are not allowed to view links. Register or Login>   
  7.     </You are not allowed to view links. Register or Login>
  8. </You are not allowed to view links. Register or Login>

Como podemos observar no hay nada del otro mundo. Simplemente un input tipo file e indicamos que se podrán elegir múltiples archivos. Por últmo, el botón submit.


Servlet

Nuestro servlet será como cualquier otro, pero añadiremos la anotación @MultipartConfig, que básicamente, identificará el servlet como un servlet multipart/form-data.

Código: Java
  1. @WebServlet(name = "UploadServlet", urlPatterns = {"/upload"})
  2. @MultipartConfig(location="D:/uploads")
  3. public class UploadServlet extends HttpServlet {
  4.     private static final long serialVersionUID = 1L;
  5.    
  6.     protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  7.             throws ServletException, You are not allowed to view links. Register or Login {
  8.         response.setContentType("text/html;charset=UTF-8");
  9.         Collection<Part> parts = request.getParts();
  10.         for(Part part : parts) {
  11.                 part.write(getFileName(part));
  12.         }
  13.     }
  14.  
  15.     @Override
  16.     protected void doGet(HttpServletRequest request, HttpServletResponse response)
  17.             throws ServletException, You are not allowed to view links. Register or Login {
  18.         processRequest(request, response);
  19.     }
  20.  
  21.     @Override
  22.     protected void doPost(HttpServletRequest request, HttpServletResponse response)
  23.             throws ServletException, You are not allowed to view links. Register or Login {
  24.         processRequest(request, response);
  25.     }
  26.  
  27.     public You are not allowed to view links. Register or Login getFileName(Part part) {
  28.         You are not allowed to view links. Register or Login contentHeader = part.getHeader("content-disposition");
  29.         You are not allowed to view links. Register or Login[] subHeaders = contentHeader.split(";");
  30.         for(You are not allowed to view links. Register or Login current : subHeaders) {
  31.             if(current.trim().startsWith("filename")) {
  32.                 int pos = current.indexOf('=');
  33.                 You are not allowed to view links. Register or Login fileName = current.substring(pos+1);
  34.                 return fileName.replace("\"", "");
  35.             }
  36.         }
  37.         return null;
  38.     }
  39. }

El atributo location sirve para especificar la ruta donde se guardarán los archivos recibidos. Ésto porsupuesto puede hacerse desde código también. En mi caso, he decidido guardarlas en D:/uploads.

Primero, recibimos todos los part mediante el método getParts() del objeto HttpServletRequest. Cada part viene a ser una parte que representa a cada elemento enviado. El payload de la petición se ve así:

Código: Text
  1. ------WebKitFormBoundaryKZUc66kZeBth3nDc
  2. Content-Disposition: form-data; name="files"; filename="jsf-scopes.png"
  3. Content-Type: image/png
  4.  
  5.  
  6. ------WebKitFormBoundaryKZUc66kZeBth3nDc
  7. Content-Disposition: form-data; name="files"; filename="navbar.png"
  8. Content-Type: image/png

Donde Content-Disposition y Content-Type son las cabeceras de las peticiones por cada part (elemento) enviado.  Es importante saber la anatomía de éstas peticiones, porque luego las usaremos para obtener ciertos datos,  como el nombre de los archivos.

Luego, recorremos los parts y por cada uno de ellos, obtenemos su nombre llamando al método getFileName el cual recibe un part y devuelve el nombre del archivo/elemento al que corresponde:

Código: Java
  1. public You are not allowed to view links. Register or Login getFileName(Part part) {
  2.         You are not allowed to view links. Register or Login contentHeader = part.getHeader("content-disposition");
  3.         You are not allowed to view links. Register or Login[] subHeaders = contentHeader.split(";");
  4.         for(You are not allowed to view links. Register or Login current : subHeaders) {
  5.             if(current.trim().startsWith("filename")) {
  6.                 int pos = current.indexOf('=');
  7.                 You are not allowed to view links. Register or Login fileName = current.substring(pos+1);
  8.                 return fileName.replace("\"", "");
  9.             }
  10.         }
  11.         return null;
  12.     }

Primero obtenemos la cabecera content-disposition la cual como vimos, almacena los datos del elemento enviado. Ahora, obtenemos los datos de esa cabecera y les llamaremos subHeaders. Los obtenemos diviendo el contenido de la cabecera por puntos y comas (;) porque así está formada la petición.

En éste punto ya tenemos los siguientes datos:

  • form-data
  • name
  • filename


El que nos interesa es filename ya que éste almacena el nombre del archivo enviado. Comprobamos si la subHeader actual comienza con 'filename', si es así,  obtenemos la posición del caracter '=' para obtener todo lo que hay hacia la derecha, que es lo que nos interesa: el nombre del archivo. Por último, reemplazamos las comillas por nada (eliminar) y eliminamos los espacios en blanco al inicio/final del nombre del archivo. El resultado, el nombre del archivo solamente.

Una vez que obtenemos el nombre del archivo asociado a cada part, los escribimos en el directorio especificado por el atributo location, que será D:/uploads:

Código: Java
  1. part.write(getFileName(part));

Por último, verificamos si se han subido  los archivos:



Eso es todo. ¿Quién dijo que Java es difícil? :P

Desconectado po6xsecpo

  • *
  • Underc0der
  • Mensajes: 45
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
    • Email
  • Skype: po6xsecpo@gmail.com
« Respuesta #1 en: Septiembre 23, 2015, 07:56:53 pm »
Me gustó mucho tu post. Sólo me quedan unas dudas:
Usualmente mapeo mis Servlets en el web.xml (Eclipse) qué me recomiendas leer para hacer uso de las anotaciones (Goolge: Anotaciones servlet, no dice mucho).

Cómo sacaste el detalle del payload o cabeceras de las peticiones? Me servirá hacer eso para debuggear (asumo, pues nunca lo he hecho)

Saludos desde noviceland.

Desconectado LKI

  • *
  • Underc0der
  • Mensajes: 60
  • Actividad:
    1.67%
  • Reputación 0
  • |Un día sin aprender nada, es un día perdido..|
    • Ver Perfil
    • Email
« Respuesta #2 en: Septiembre 25, 2015, 06:15:35 pm »
Muy bueno se agradece tu aporte !! , seria bueno algun tuto con Spring MVC  :D

Saludos !
Ser mejor cada día es mi meta

 =LKI=

 

¿Te gustó el post? COMPARTILO!



× Neptuno × Copia archivos de manera sigilosa

Iniciado por Mortal_Poison

Respuestas: 6
Vistas: 1803
Último mensaje Junio 06, 2018, 03:54:48 pm
por PikachuDorado
Descargar archivos de la web usando un progressBar

Iniciado por ProcessKill

Respuestas: 0
Vistas: 2216
Último mensaje Febrero 24, 2010, 04:16:01 pm
por ProcessKill
Buscador de archivos

Iniciado por rollth

Respuestas: 1
Vistas: 1941
Último mensaje Enero 17, 2016, 03:11:59 pm
por Hu3c0