Struts 2 - Carga de archivos

El marco Struts 2 proporciona soporte integrado para procesar la carga de archivos mediante "Carga de archivos basada en formularios en HTML". Cuando se carga un archivo, normalmente se almacenará en un directorio temporal y su clase Action debe procesarlo o moverlo a un directorio permanente para garantizar que no se pierdan los datos.

Note - Los servidores pueden tener una política de seguridad que le prohíbe escribir en directorios que no sean el directorio temporal y los directorios que pertenecen a su aplicación web.

La carga de archivos en Struts es posible a través de un interceptor predefinido llamado FileUpload interceptor que está disponible a través de la clase org.apache.struts2.interceptor.FileUploadInterceptor e incluido como parte de ladefaultStack. Aún así, puede usar eso en su struts.xml para establecer varios parámetros como veremos a continuación.

Crear archivos de vista

Comencemos con la creación de nuestra vista, que será necesaria para navegar y cargar un archivo seleccionado. Así que creemos unindex.jsp con un formulario de carga HTML simple que permite al usuario cargar un archivo -

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <title>File Upload</title>
   </head>
   
   <body>
      <form action = "upload" method = "post" enctype = "multipart/form-data">
         <label for = "myFile">Upload your file</label>
         <input type = "file" name = "myFile" />
         <input type = "submit" value = "Upload"/>
      </form>
   </body>
</html>

Hay un par de puntos que vale la pena señalar en el ejemplo anterior. Primero, el enctype del formulario se establece enmultipart/form-data. Esto debe configurarse de modo que el interceptor de carga de archivos gestione correctamente las cargas de archivos. El siguiente punto a tener en cuenta es el método de acción del formulario.upload y el nombre del campo de carga del archivo, que es myFile. Necesitamos esta información para crear el método de acción y la configuración de struts.

A continuación, creemos un archivo jsp simple success.jsp para mostrar el resultado de la carga de nuestro archivo en caso de que tenga éxito.

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>File Upload Success</title>
   </head>
   
   <body>
      You have successfully uploaded <s:property value = "myFileFileName"/>
   </body>
</html>

A continuación se muestra el archivo de resultados error.jsp en caso de que haya algún error al cargar el archivo -

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>File Upload Error</title>
   </head>
   
   <body>
      There has been an error in uploading the file.
   </body>
</html>

Crear clase de acción

A continuación, creemos una clase Java llamada uploadFile.java que se encargará de cargar el archivo y almacenar ese archivo en una ubicación segura -

package com.tutorialspoint.struts2;

import java.io.File;
import org.apache.commons.io.FileUtils;
import java.io.IOException; 

import com.opensymphony.xwork2.ActionSupport;

public class uploadFile extends ActionSupport {
   private File myFile;
   private String myFileContentType;
   private String myFileFileName;
   private String destPath;

   public String execute() {
      /* Copy file to a safe location */
      destPath = "C:/apache-tomcat-6.0.33/work/";

      try {
         System.out.println("Src File name: " + myFile);
         System.out.println("Dst File name: " + myFileFileName);
     	    	 
         File destFile  = new File(destPath, myFileFileName);
         FileUtils.copyFile(myFile, destFile);
  
      } catch(IOException e) {
         e.printStackTrace();
         return ERROR;
      }

      return SUCCESS;
   }
   
   public File getMyFile() {
      return myFile;
   }
   
   public void setMyFile(File myFile) {
      this.myFile = myFile;
   }
   
   public String getMyFileContentType() {
      return myFileContentType;
   }
   
   public void setMyFileContentType(String myFileContentType) {
      this.myFileContentType = myFileContentType;
   }
   
   public String getMyFileFileName() {
      return myFileFileName;
   }
   
   public void setMyFileFileName(String myFileFileName) {
      this.myFileFileName = myFileFileName;
   }
}

los uploadFile.javaes una clase muy simple. Lo importante a tener en cuenta es que el interceptor FileUpload junto con el Interceptor de parámetros hace todo el trabajo pesado por nosotros.

El interceptor FileUpload pone a su disposición tres parámetros de forma predeterminada. Se nombran con el siguiente patrón:

  • [your file name parameter] - Este es el archivo real que ha subido el usuario. En este ejemplo será "myFile"

  • [your file name parameter]ContentType- Este es el tipo de contenido del archivo que se cargó. En este ejemplo será "myFileContentType"

  • [your file name parameter]FileName- Este es el nombre del archivo que se cargó. En este ejemplo será "myFileFileName"

Los tres parámetros están disponibles para nosotros, gracias a los Struts Interceptors. Todo lo que tenemos que hacer es crear tres parámetros con los nombres correctos en nuestra clase Action y automáticamente estas variables se conectan automáticamente para nosotros. Entonces, en el ejemplo anterior, tenemos tres parámetros y un método de acción que simplemente devuelve "éxito" si todo va bien, de lo contrario devuelve "error".

Archivos de configuración

A continuación se muestran las propiedades de configuración de Struts2 que controlan el proceso de carga de archivos:

No Señor Propiedades y descripción
1

struts.multipart.maxSize

El tamaño máximo (en bytes) de un archivo que se aceptará como carga de archivo. El valor predeterminado es 250M.

2

struts.multipart.parser

La biblioteca utilizada para cargar el formulario de varias partes. Por defecto esjakarta

3

struts.multipart.saveDir

La ubicación para almacenar el archivo temporal. Por defecto es javax.servlet.context.tempdir.

Para cambiar cualquiera de estas configuraciones, puede usar constant en el archivo struts.xml de su aplicación, como hice para cambiar el tamaño máximo de un archivo que se cargará.

Déjanos tener nuestro struts.xml como sigue -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!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.devMode" value = "true" />
   <constant name = "struts.multipart.maxSize" value = "1000000" />
   <package name = "helloworld" extends = "struts-default">
      <action name = "upload" class = "com.tutorialspoint.struts2.uploadFile">
         <result name = "success">/success.jsp</result>
         <result name = "error">/error.jsp</result>
      </action>
   </package>
</struts>

Ya que, FileUploadEl interceptor es parte de la pila predeterminada de interceptores, no es necesario configurarlo explícitamente. Pero puede agregar la etiqueta <interceptor-ref> dentro de <action>. El interceptor fileUpload toma dos parámetros(a) maximumSize y (b) allowedTypes.

El parámetro maximumSize establece el tamaño máximo de archivo permitido (el valor predeterminado es aproximadamente 2 MB). El parámetro allowedTypes es una lista separada por comas de tipos de contenido aceptado (MIME) como se muestra a continuación:

<action name = "upload" class = "com.tutorialspoint.struts2.uploadFile">
   <interceptor-ref name = "basicStack">
   <interceptor-ref name = "fileUpload">
      <param name = "allowedTypes">image/jpeg,image/gif</param>
   </interceptor-ref>
   <result name = "success">/success.jsp</result>
   <result name = "error">/error.jsp</result>
</action>

A continuación se muestra el contenido de web.xml archivo -

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee" 
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">
   
   <display-name>Struts 2</display-name>
   
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   
   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

Ahora haga clic derecho en el nombre del proyecto y haga clic en Export > WAR Filepara crear un archivo War. Luego, implemente este WAR en el directorio de aplicaciones web de Tomcat. Finalmente, inicie el servidor Tomcat e intente acceder a la URLhttp://localhost:8080/HelloWorldStruts2/upload.jsp. Esto producirá la siguiente pantalla:

Ahora seleccione un archivo "Contactos.txt" usando el botón Examinar y haga clic en el botón de carga que cargará el archivo en su servicio y debería ver la página siguiente. Puede verificar que el archivo cargado debe estar guardado en C: \ apache-tomcat-6.0.33 \ work.

Tenga en cuenta que FileUpload Interceptor elimina el archivo cargado automáticamente, por lo que tendría que guardar el archivo cargado mediante programación en alguna ubicación antes de que se elimine.

Error de mensajes

El interceptor fileUplaod utiliza varias claves de mensaje de error predeterminadas:

No Señor Clave y descripción del mensaje de error
1

struts.messages.error.uploading

Un error general que ocurre cuando el archivo no se pudo cargar.

2

struts.messages.error.file.too.large

Ocurre cuando el archivo cargado es demasiado grande según lo especificado por maximumSize.

3

struts.messages.error.content.type.not.allowed

Ocurre cuando el archivo cargado no coincide con los tipos de contenido esperados especificados.

Puede anular el texto de estos mensajes en WebContent/WEB-INF/classes/messages.properties archivos de recursos.