Carga de archivo, Interceptor FileUpload con Struts2

En este ejemplo veremos nuevamente el uso interceptores, como ya hemos mencionado en otros post, Struts2 posee una amplia gama de funciones que permiten hacer mas ágil el desarrollo y que están puestas a disposición de los desarrolladores a través de los interceptores que vienen por default.

En esta ocasión veremos un interceptor que nos permite realizar una de las funciones con la que comúnmente nos topamos en el desarrollo de aplicaciones empresariales, se trata de la carga de archivos.

El interceptor FileUpload está dado de alta en la pila de interceptores del paquete default que maneja Struts2.

org.apache.struts2.interceptor.FileUploadInterceptor

Si ya tenemos configurado nuestro proyecto solo es necesario agregar estas librerías:

  • commons-fileupload-1.2.1.jar
  • commons-io-1.3.2.jar

Si no recuerdas que otras librerías son requeridas o como configurar tu proyecto para usar Struts2 puedes regresar al primer ejemplo que vimos en este mismo blog sobre como hacerlo:

Lo primero que haremos es crear un formulario de carga de archivos, el código lo muestro a continuación:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Carga de archivos con interceptores</title>
</head>
<body>
<h1>Carga de archivos con interceptores</h1>
<s:form action="CargaArchivo" method="post" enctype="multipart/form-data">
<s:file name="archivo" label="Carga Archivo"/>
<s:submit value="Subir" align="center"/>
</s:form>
</body>
</html>

Despues creamos la clase AccionCargaArchivo que se encargará de recibir y manejar el contenido del archivo.

package ejemplos.struts2.accion;
import com.opensymphony.xwork2.ActionSupport;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class AccionCargaArchivo extends ActionSupport {
private File archivo;
private String archivoContentType;
private String archivoFileName;
private String datos = "";

public String execute() {
try{
BufferedReader entrada = new BufferedReader( new FileReader( archivo ) );
if ( archivoContentType.equals("text/plain")){
String aux;
while((aux = entrada.readLine()) != null){
datos += aux + "n";
}
}
}catch(Exception e){
e.printStackTrace();
}
return SUCCESS;
}

public File getArchivo() {
return archivo;
}

public void setArchivo(File archivo) {
this.archivo = archivo;
}

public String getArchivoContentType() {
return archivoContentType;
}

public void setArchivoContentType(String archivoContentType) {
this.archivoContentType = archivoContentType;
}

public String getArchivoFileName() {
return archivoFileName;
}

public void setArchivoFileName(String archivoFileName) {
this.archivoFileName = archivoFileName;
}

public String getDatos() {
return datos;
}

public void setDatos(String datos) {
this.datos = datos;
}
}

Del la clase Action anterior observa cuidadosamente las siguientes variables:

  • File nombreDeArchivo;
  • String nombreDeArchivoContentType;
  • String nombreDeArchivoFileName;

Como puedes ver la variable de tipo File tiene un nombre arbitrario, sin embargo las otras dos deben cumplir con un formato establecido para que el interceptor pueda encontrarlas y establecer los datos correspondientes al tipo de contenido y al nombre del archivo.

  • archivo – Es el nombre del archivo.
  • archivoContentType – Contiene el tipo de contenido del archivo.
  • archivoFileName – Contiene el nombre del archivo tal como fue almacenado en el servidor.

Esto es todo lo que debe hacerse para que el Framework a través del inteceptor tome el archivo y lo relacione con las variables que declaramos en el Action.

También haremos la jsp de respuesta, que solo mostrará algunos datos del archivo que se esta subiendo al servidor.

El código es el siguiente:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>El archivo fu&eacute; recibido con exito!</h1>
El tipo del contenido es : <s:property value="archivoContentType"/><br>
Nombre del archivo es : <s:property value="archivoFileName"/><br>
Nombre del archivo temporal : <s:property value="archivo.name"/><br>
Contenido del archivo :<br>
<s:textarea name="dat" value="%{datos}" cols="50" />
</body>
</html>

y por último haremos cambios necesarios en el archivo de configuración de Struts2 para hacer referencia a las clases y jsps que acabamos de crear.

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<package name="default" namespace="/" extends="struts-default">
<action name="FormularioCargaArchivo" >
<result>/formularioDeCargaDeArchivo.jsp</result>
</action>
<action name="CargaArchivo" class="ejemplos.struts2.accion.AccionCargaArchivo">
<result>/archivoCargado.jsp</result>
<result name="input">/formularioDeCargaDeArchivo.jsp</result>
</action>
</package>
</struts>

El código fuente de todos los archivos aqui:

Si corres el ejemplo y mandas llamar al formulario de carga de archivo debe aparecerte algo como lo siguiente:

formularioDeCargaDeArchivo.jsp

Como puedes ver nos aparece el campo para especificar el archivo que queremos subir.

Para este ejemplo solo cargaremos archivos de texto plano y visualizaremos el contenido.


Damos click en el boton de Subir y tendremos una respuesta como esta:


En esta jsp mostramos el tipo de datos del archivo, el nombre del archivo y el nombre que tendrá temporalmente en el servidor mientras es procesado durante el tiempo que se ejecute nuestra acción.

Despues mostramos simplemente el contenido. Listo ya tenemos el ejemplo.

Es importante que sepas que el archivo temporal se removera del servidor una vez que el ciclo de llamada a la acción termine.


Espero que te sirva este ejemplo, si tienes alguna duda o comentario hazmelo saber. Hasta el proximo post.

11 comentarios en «Carga de archivo, Interceptor FileUpload con Struts2»

  1. Es su blog de mucha ayuda muy bien explciado quisiera solicitarle su ayuda y que muestren un ejm donde se conecte a mysql con struts2 sin utilizar hibernate gracias

    Responder
  2. Hola quizá mas adelante haga alguno, sin embargo, Struts2 por si solo no se utiliza para conectarse con alguna base de datos especifica. La conexión a base de datos se controla desde otra capa de código que se solo se encargue manejar los accesos a base de datos, de este modo separas y haces mas claro tu proyecto. ¿Tienes algún problema especifico para saber como ayudarte? Perdón por la tardanza.

    Responder
  3. Quisiera hacerte una consulta. Soy nuevo en este framework y estoy trabajando con mapeos por annotations en vez de con xml. los parámetros de configuración los escribo en un struts.properties

    Quiero subir un archivo e hice esta clase. Cuando lo corro llega bien al execute y crea en el fichero correspondiente el .tmp, pero todas las variables en la clase están en null y no puedo entender como es la lógica. Mis archivos subido quedan en .tmp y obviamente al estar todo en null no puedo hacer nada.

    Responder
    • Hola Anónimo, quizá estas tratando de hacer uso del archivo fuera del ciclo de petición y respuesta, durate el método execute debes hacer algo con el archivo, como guardar una copia en otra ruta o meterla en una base de datos para que no se pierda, o es durante la ejecución del execute que se pierde y las variables están en null?

      Responder
  4. Que tal, el archivo se genera dinámicamente por el Framework y este mismo te pasa la referencia al mismo en la variable archivo. Tu debes utilizar esta referencia para escribir nuevamente o copiar los datos que necesites en una ruta diferente. Recuerda que al completar el ciclo de llama, el framework borrará este archivo temporal… saludos

    Responder
  5. Muy fácil y muy bien explicado, si quisieramos subir varios archivos como sería?? sin tener que poner varios . Es decir:

    Archivo Adjunto (examinar)
    archivo adjunto1

    Subir

    que se puedan adjuntar una lista de adjuntos…

    Muchas gracias y un saludo

    Responder
  6. buenas tardes.. estoy desarrollando un aplicacion en struts 2 netbeasns y quisiera saber como se puede realizar la operacion de buscar un archivo en una BD y mostrarlo y de no lo encuentra que envie un mensaje.. gracias

    Responder
    • ¿Estas almacenando el archivo en la base de datos? ¿De que tipo es? Necesitas almacenar el nombre del archivo en otro campo para hacer la búsqueda, ¿O la búsqueda la harás sobre el contenido del archivo? Saludos

      Responder

Deja un comentario

eight + = sixteen