Framework Struts para Java: arquitectura y componentes

En el post de hoy vamos a sumergirnos en uno de los frameworks más influyentes en los inicios del desarrollo web con Java: Apache Struts. Aunque hoy día muchos proyectos se basan en Spring, aún es importante entender el legado que dejó Struts (sobre todo Struts 1), que durante muchos años fue el estándar de facto para construir aplicaciones web MVC en Java. De hecho, es muy probable que en algún momento de tu carrera profesional te toque dar mantenimiento a una aplicación Legacy que todavía se apoye en dicho framework.

 

 

Este post te ayudará a entender cómo funciona esta tecnología, qué piezas lo componen y cuál es el flujo completo de una petición HTTP típica gestionada con Struts. También repasaremos cuáles son los ficheros de configuración más relevantes y cómo se conectan entre sí.

 

💦 ¿Qué es el framework Struts?

 

Struts es un framework de código abierto desarrollado por Apache Software Foundation que proporciona una estructura robusta para desarrollar aplicaciones web Java siguiendo el patrón MVC (Modelo-Vista-Controlador).

 

Aunque hoy día está en desuso, Struts 1 fue pionero en su época (te hablo de hace unos 20 años), y ofrecía una forma clara de separar lógica de negocio, vistas y controladores. Este framework gestionaba la navegación de la aplicación a través de ficheros de configuración XML, y ponía énfasis en reutilizar componentes como formularios ("ActionForm") y acciones ("Action").

 

Años más tarde nació Struts 2, una reescritura profunda basada en WebWork, pero sin duda Struts 1 fue mucho más popular y hoy en día está mucho más extendido en grandes empresas y proyectos Legacy. Básicamente, el problema con Struts 2 fue que su lanzamiento al mercado llegó con varios años de retraso con respecto al framework Spring MVC... así que, como os podéis imaginar, le fue imposible competir con el monstruo y el resto es historia.

 

 

🧱 Arquitectura básica de Struts

 

En líneas generales, la arquitectura de Struts 1 implementa el modelo MVC clásico, aunque con algunos matices propios. Se puede resumir así:

  • Modelo: las clases Java que contienen la lógica de negocio, acceden a bases de datos o servicios. Esto se hace normalmente mediante Beans, DAOs y Services.

  • Vista: esta capa normalmente está implementada con páginas JSP (JavaServer Pages), encargadas de mostrar los datos al usuario.

  • Controlador: es el núcleo de Struts. Está representado por el componente central llamado ActionServlet, que recibe la petición del usuario, la enruta a la clase "Action" correspondiente y finalmente indica la vista a la que debe ser redigirida.

 

Todo este flujo está orquestado mediante el archivo de configuración "struts-config.xml", que actúa como el mapa de rutas, componentes y navegación.

 

  

🔍 Componentes principales de Struts

 

A continuación, vamos a desgranar los componentes más importantes que hacen posible el funcionamiento de Struts 1. Serían los siguientes:

 

🌐 Browser (cliente web)

El navegador envía peticiones HTTP al servidor. Estas solicitudes del usuario suelen provenir de formularios HTML o enlaces generados por JSP. En Struts, todas estas peticiones van dirigidas a una única URL controlada por el "ActionServlet".

 

🎯 Action

Es una clase Java perteneciente a la librería "org.apache.struts.action.Action" (específica de Struts). Representa la lógica de control, y se encarga de procesar la petición, invocar a la lógica de negocio y posteriormente determinar a qué vista (JSP) debe redirigirse el resultado.

 

🔎 Ejemplo de Action: 


public class LoginAction extends Action {
  public ActionForward execute(...) {
    // lógica de login
    return mapping.findForward("success");
  }
}

 

📝 ActionForm

Es una clase que se utiliza para recoger los datos introducidos por el usuario en un formulario web. Cada formulario HTML se asocia con una clase "ActionForm" que encapsula los datos. Esta clase puede integrar validaciones de forma declarativa (si es necesario).

 

🔎 Ejemplo de ActionForm: 


public class LoginForm extends ActionForm {
  private String username;
  private String password;
  // Getters y setters
}
 

 

💦 Fichero struts-config.xml

Es el corazón de la configuración de Struts 1. Aquí se definen las relaciones entre formularios, acciones, forwards, validaciones y vistas. Su estructura puede parecer rígida hoy día, pero en su momento permitía un control detallado de toda la app. Toda la configuración inicial se define en este fichero XML.

 

Los tags más importantes de este fichero de configuración son los siguientes:

  • <form-beans>
  • <global-exceptions>
  • <action-mappings>
  • <message-resources>
  • <plug-in> 

 

 🔎 Ejemplo de <action-mappings> de struts-config.xml: 

 
<action-mappings>
<action path="/login"
        type="com.ejemplo.LoginAction"
        name="loginForm"
        input="/login.jsp"
        scope="request"
        validate="true">
  <forward name="success" path="/bienvenido.jsp"/>
</action>
</action-mappings>
 

 

📦 Fichero web.xml

Es el descriptor de despliegue estándar en aplicaciones Java EE. En este fichero debemos declarar el "ActionServlet", que es el punto de entrada de todas las peticiones Struts. También se definen filtros, listeners, etc... En particular, en <url-pattern> hay que definir el patrón de las peticiones web que deben ser capturadas por el framework de Struts. Típicamente se suelen capturar las peticiones terminadas en ".do" pero, como estamos diciendo, este patrón sería configurable.

 

 🔎 Ejemplo de configuración de Struts en web.xml:  


<servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/struts-config.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.do</url-pattern>
</servlet-mapping>


⚙️ ActionServlet

Es el controlador principal de Struts. Todas las peticiones terminadas en ".do" son procesadas por este servlet. Su trabajo es analizar el fichero "struts-config.xml", buscar la clase "Action" correspondiente y delegar la ejecución.

🚸 Puntualizar que normalmente se procesan las peticiones terminadas en ".do" pero, en realidad, este patrón puede ser configurado en el <url-pattern> del fichero web.xml (tal y como hemos visto en el punto anterior). 

 

🧾 JSP (JavaServer Pages)

La capa de presentación de la aplicación suele construirse con páginas JSP. Aquí se pueden utilizar etiquetas (tags) para la integración con los formularios y para mostrar los datos de forma dinámica. Son la interfaz que el usuario final ve.

Para utilizar los tags podemos apoyarnos tanto en JSTL (librería de tags estándar de JSP) como en las etiquetas específicas de Struts (Taglibs o JSP Tag Libraries). Esto nos permitirá usar tags tales como "<html:form>", "<html:text>" y otros.

 

 

🔍 Tags del fichero struts-config.xml

 

A continuación, vamos a hacer un repaso breve de la funcionalidad asociada a cada una de las principales tags existentes en el fichero struts-config.xml. 

 

  • <form-beans>

    • <form-bean>

      • Declara el objeto JavaBean que Struts usa para recoger, resetear y validar los parámetros HTTP antes de entrar en tu "Action".

      • La clase Java debe extender de ActionForm e implementar métodos reset() y validate(). También debe disponer de los atributos para recoger los campos del HTML.

  • <global-exceptions>

    • Define cómo gestionar excepciones lanzadas por cualquier Action del módulo, sin tener que repetir la configuración en cada uno de ellos.

  • <action-mappings>

    • <action>

      • Indica la clase "Action" a la que se debe redirigir la petición capturada y el jsp "Forward" al que se debe navegar si toda la lógica va bien. 

      • <forward>

        • Destino al que se navega si todo va bien

  • <message-resources>

    • Grupo de mensajes utilizados por el framework.

  • <plug-in>

    • Permite conectar componentes de inicialización del propio Struts (no del contenedor Java EE). Esta es la forma “oficial” de ejecutar código en el arranque de Struts, antes de que el framework se dedique a atender peticiones.

    • Esta funcionalidad se ejecuta en el init del módulo Struts (no se trata de algo que se intercepte en cada cada request). Se utiliza para cargar configuración adicional: validaciones, cachés, carga dinámica de mappings…

       

       

💬 Atributos de las etiquetas Action y Forward 

 

Entrando un poco más en detalle, vamos a enumerar los atributos principales de la etiqueta <action>, la cual podríamos considerar como la más "importante" del XML. Son los siguientes:

  • path: URL lógica de Struts. Con el mapeo "*.do" del proyecto, esta acción atiende peticiones del tipo "/path.do". Por ejemplo, si tenemos un path del tipo "/ConsultaPedidos", entonces se atenderán las peticiones "ConsultaPedidos.do"

  • type: Es la clase Java que Struts instanciará para procesar la petición que llega al path.

    • Ejemplo: type="com.universo.gestor.web.action.EmpleadoAction"
  • name: Indica el Form Bean asociado. Esa clase "ActionForm" debe estar declarada en el apartado <form-beans>.

  • scope: Alcance de la petición.

  • input: Destino al que volver si la validación falla. Si el "ActionForm" (o el Validator) generan errores, Struts hace un forward a este destino.

  • parameter: Este tag se utiliza para activar acciones multi-método. El parámetro indicará qué método de la clase "Action" debe ser invocado. Obviamente, el valor de ese parámetro deberá ser provisionado previamente en la petición para que pueda ser capturado por el ActionServlet. Por cierto, si no se define parameter siempre se ejecutará el método execute() del Action.

    • Ejemplo: parameter="metodo"
  • unknown: En el XML sólo puede haber una acción con unknown="true", que se utilizará para gestionar URLs no mapeadas.

  • validate: Si este tag es true, entonces Struts llamará a la validación antes de ejecutar la acción. Esto es, se llamará previamente al método validate() del ActionForm.

 

Para terminar con este XML, también podemos echarle un vistazo a los atributos principales de la etiqueta <forward>. Serían los siguientes:

  • name: Nombre lógico que usarás desde el código

  • path: Destino al que se navega si todo va bien

  • redirect: si este tag es true, entonces se tratará de un redirect HTTP y el navegador cambiaría la URL. Por contra, si el tag es false, se realizaría un forward interno.

  

 

🔁 Flujo de una petición en Struts

 

Para que quede más clara la integración de todos los componentes anteriores, paso a comentar ahora cómo sería el proceso típico que sigue una petición en una aplicación Struts 1.

  1. El usuario accede a una URL o envía un formulario desde su navegador (/login.do).

  2. El ActionServlet intercepta la petición gracias al mapeo definido en web.xml (recordemos, la etiqueta <url-pattern>).

  3. Lee la configuración de struts-config.xml y determina tanto el "ActionForm" como el "Action" que deben participar en la petición.

  4. Carga y valida el ActionForm (en el caso de que se haya implementado validación en dicha clase).

  5. Ejecuta la lógica existente en el Action.

  6. El Action finalmente devuelve un "ActionForward" indicando cuál debe ser la siguiente vista que debe mostrarse en el navegador.

  7. El ActionServlet redirige a la vista correspondiente (normalmente una página JSP).

  8. La página JSP muestra la respuesta visual al usuario.

 

Este flujo garantiza una separación clara de responsabilidades. Hay que tener en cuenta que esto fue la base de muchos proyectos empresariales en Java durante más de una década: antes del nacimiento de Struts no existía ningún framework universal que permitiese guiar la creación estructurada de aplicaciones siguiendo el patrón MVC.

 

 

🧭 Conclusión

 

Aunque Struts ha sido oficialmente declarado obsoleto y sustituido en la mayoría de proyectos modernos por frameworks como Spring MVC o JSF, sigue siendo importante conocerlo para poder completar el mantenimiento de los proyectos Legacy. Adicionalmente, conocer Struts también te vendrá bien para entender la evolución de los frameworks Java, o incluso para entrevistas técnicas donde te pidan conocimiento de arquitectura MVC clásica.

 

Su enfoque basado tanto en configuración XML como en clases específicas (Action y ActionForm) sentó las bases para muchos frameworks posteriores. Si alguna vez te enfrentas a una app que lo usa, al menos ahora ya sabes por dónde empezar.

 

¡Nos vemos en el siguiente post!

Saludos.

 

Comentarios

Entradas populares de este blog

Componentes y Ventanas de Java Swing

Cómo validar datos en Spring Boot con anotaciones @Valid

Patrones de Diseño GOF (Gang of Four)