VERSIONES
- 15/08/2013 (Primera publicación)
- 08/03/2014:
- Actualización del ejemplo a Struts 2.3.16.1 debido a vulnerabilidad en libreria FileUpload
15/08/2013
En el tip anterior vimos el mecanismo proporcionado por Struts 2 para la subida de ficheros. Si se necesitara subir más de un fichero en un formulario, en principio bastaría con definir para cada fichero a subir los atributos necesarios con sus getters y setters, no es muy elegante pero funciona. El problema lo tendremos si el número de ficheros a subir es dinámico, esto es, no está preestablecido por lo que esta aproximación no nos serviría. Afortunadamente, Struts 2 soporta subidas múltiples de ficheros de forma sencilla y elegante: haciendo que los ficheros a subir se guarden en una lista de File.
Si retomamos el proyecto del tip anterior, el Action quedaría ahora así:
package com.danielme.tips.struts2.actions; import java.io.File; import java.util.LinkedList; import java.util.List; import com.opensymphony.xwork2.ActionSupport; /** * * @author danielme.com * */ public class SubidaFicheroAction extends ActionSupport { private static final long serialVersionUID = 1L; private List<File> uploadFichero = new LinkedList<File>(); private List<String> uploadFicheroFileName = new LinkedList<String>(); private List<String> uploadFicheroContentType = new LinkedList<String>(); /** ACCIONES **/ public String inicio() { return INPUT; } public String enviar() { if (uploadFichero.isEmpty()) { return INPUT; } else { return SUCCESS; } } /** GETTERS Y SETTERS **/ public List<File> getUploadFichero() { return uploadFichero; } public void setUploadFichero(List<File> uploadFichero) { this.uploadFichero = uploadFichero; } public List<String> getUploadFicheroFileName() { return uploadFicheroFileName; } public void setUploadFicheroFileName(List<String> uploadFicheroFileName) { this.uploadFicheroFileName = uploadFicheroFileName; } public List<String> getUploadFicheroContentType() { return uploadFicheroContentType; } public void setUploadFicheroContentType(List<String> uploadFicheroContentType) { this.uploadFicheroContentType = uploadFicheroContentType; } }
En el formulario definimos o generamos dinámicamente según sea el caso un campo para cada fichero con el nombre del atributo de la lista, por ejemplo:
<s:form action="subirFicheroAction" method="POST" enctype="multipart/form-data"> <s:file name="uploadFichero"/> <s:file name="uploadFichero"/> <s:file name="uploadFichero"/> <s:submit key="send"/> </s:form>
Y listo. Para recuperar los ficheros subidos, bastaría con iterar sobre las listas. El código de resultado.jsp
uploadFicheroFileName: <ul> <s:iterator value="uploadFicheroFileName"> <li><s:property /></li> </s:iterator> </ul> <br> uploadFicheroContentType <ul> <s:iterator value="uploadFicheroContentType"> <li><s:property /></li> </s:iterator> </ul>
El resultado final del proyecto de ejemplo es el siguiente:
El proyecto completo para Maven se encuentra en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.
Se puede con input type=file multiple? Mi mentalidad millenial me dice que qué hueva crear un input file para cada archivos que se va a subir.
Sí, puedes hacerlo para navegadores que soporten HTML5. Lo indicas en el s:file con multiple=»multiple».