En el post de hoy vamos a ir repasando los pasos necesarios para llevar a buen término la creación de un proyecto web clásico con Struts 1 en Eclipse. Aunque se trata de un framework legacy, Struts 1 sigue siendo útil en proyectos heredados o formativos. A diferencia de su sucesor, Struts 2, la versión 1 fue mucho más utilizada en el mundo Java empresarial entre los años 2000 y 2010, y su estructura basada en MVC puro la convierte en un excelente ejemplo para entender cómo funcionaban los frameworks Java EE en sus primeras etapas.
🚀 ¿En qué consiste Struts?
Apache Struts es un framework web basado en el patrón MVC (Modelo-Vista-Controlador) que permite separar la lógica de negocio, la presentación y el control de flujo. Aunque Struts 2 introdujo mejoras notables, Struts 1 fue el framework más implantado en el sector durante años, especialmente por su integración sencilla con JSP y Servlets clásicos.
Struts 1 ofrece un enfoque estructurado para gestionar formularios, validaciones, y la navegación entre páginas. Destaca el uso de elementos clave como "Action", "Form", "ActionServlet", así como la utilización de ficheros de configuración XML como "struts-config.xml".
🧱 Pasos para crear un Dynamic Web Project con Struts 1
Vista la mini-presentación anterior, a continuación te voy a mostrar cómo crear en Eclipse un proyecto web básico con Struts 1 al estilo legacy (esto es, sin usar Maven).
✅ Herramientas requeridas
-
Eclipse IDE for Enterprise Java
-
Apache Tomcat 9 configurado en Eclipse (hay que tener en cuenta que Struts no funciona con versiones posteriores de Tomcat).
-
JDK 8 (ideal para proyectos heredados)
-
JARs de Struts 1.3.10 y sus dependencias
🛠️ Construcción del proyecto paso a paso
1. Creación del proyecto
En primer lugar, abrimos Eclipse y creamos nuevo proyecto con la opción FILE - NEW - DYNAMIC WEB PROJECT. Tienes que seleccionar el nombre del proyecto, tu runtime de Tomcat y la versión 2.5 del módulo web.
Pulsamos NEXT e indicamos el "Content directory" que va a almacenar el contenido Web. En mi caso voy a utilizar "src/main/webapp", pero tú puedes poner la ruta que quieras. Antiguamente también se utilizaba mucho la ruta "WebContent".

Pulsamos FINISH y se lanzará la creación de nuestro proyecto. Como vemos, en este caso concreto ha quedado dado de alta con Java 8 y con Tomcat 9.

2. Añadir los JARs de Struts
A continuación, al tratarse de un proyecto no mavenizado, tendremos que copiar los siguientes JARs a la carpeta "webapp/WEB-INF/lib" (como hemos dicho en el punto anterior, en proyecto más antiguos esta carpeta podría denominarse "WebContent/WEB-INF/lib" o algo similar):
- struts-core-1.3.10.jar
- struts-taglib-1.3.10.jar
- commons-beanutils-1.8.3.jar
- commons-chain-1.1.jar
- commons-digester-1.8.jar
- commons-logging-1.1.1.jar
- commons-validator-1.3.1.jar
- commons-collections-3.2.1.jar
- jstl-1.2.jar
- oro-2.0.8.jar
No es necesario incluir la librería "servlet-api.jar", ya que se encuentra embebida en el propio contenedor del servidor Tomcat.
Adicionalmente, también debemos añadir el DTD de Struts en la carpeta "webapp/WEB-INF/dtds". En nuestro caso añadiremos el objeto "struts-config_1_3.dtd".
💻 Estructura esperada del proyecto
La estructura global esperada debería ser algo como lo siguiente, con pequeñas variantes en función de cómo hayas creado tu propio proyecto.
3. Configuración Web
Hay que configurar el fichero web.xml, donde en <servlet> tendremos que definir el "ActionServlet" de Struts y en <servlet-mapping> habrá que establecer el patrón ".do" que va a ser capturado para la peticiones entrantes.
🔎 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Struts1 Login</display-name>
<!-- Filtro de codificación opcional -->
<filter>
<filter-name>SetCharacterEncoding</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SetCharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Struts ActionServlet -->
<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>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<!-- Todas las acciones terminan en .do -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
4. Configuración Struts
Hay que establecer la configuración de Struts en el fichero "struts-config.xml". En este XML es donde se va a indicar el mapeo de formularios y acciones. Concretamente, vamos a establecer la siguiente configuración básica:
- En el tag <form-bean> vamos a apuntar a la clase "LoginForm.java".
- En el tag <action> vamos a apuntar a la clase "LoginAction.java".
- En el tag <DOCTYPE struts-config> tenemos que enlazar con la ruta donde pusimos anteriormente el DTD de Struts, esto es, con la ubicación "./dtds/struts-config_1_3.dtd".
- En el tag <message-resources> apuntaremos al fichero "ApplicationResources.properties" donde se almacenarán las propiedades que vayamos definiendo para Struts.
🔎 struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"./dtds/struts-config_1_3.dtd">
<struts-config>
<!-- Form beans -->
<form-beans>
<form-bean name="loginForm" type="com.universo.struts1.form.LoginForm"/>
</form-beans>
<!-- Action mappings -->
<action-mappings>
<action
path="/login"
type="com.universo.struts1.action.LoginAction"
name="loginForm"
scope="request"
validate="true"
input="/login.jsp">
<!-- forwards lógicos -->
<forward name="success" path="/success.jsp"/>
<forward name="failure" path="/login.jsp"/>
</action>
</action-mappings>
<!-- Nombre del fichero de propiedades -->
<message-resources
parameter="com.universo.struts1.resources.ApplicationResources" />
</struts-config>
5. Configuración de las propiedades Struts
Tenemos que crearnos el fichero "ApplicationResources.properties" donde ser irán almacenando las propiedades que posteriormente requieran ser utilizadas por Struts.
🔎 ApplicationResources.properties
# Mensajes de validación del formulario de login
error.username.required = El usuario es obligatorio.
error.password.required = La contraseña es obligatoria.
# Error de login (credenciales incorrectas)
error.login.invalid = Usuario o contraseña incorrectos.
6. Implementación del Form de Struts
A continuación, procedemos a implementar el Form, que deberá contener los campos del formulario y la validación de los datos. Recordemos que Struts va a buscar de forma automática las validaciones invocando al método validate() del Form.
🔎 LoginForm.java
package com.universo.struts1.form;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
public class LoginForm extends ActionForm {
/**
*
*/
private static final long serialVersionUID = 1L;
private String username;
private String password;
// Validación simple del lado servidor (Struts 1)
@Override
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
// Validación del campo username
if (username == null || username.isEmpty()) {
// Clave definida en ApplicationResources.properties
errors.add("username", new ActionMessage("error.username.required"));
}
// Validación del campo password
if (password == null || password.isEmpty()) {
errors.add("password", new ActionMessage("error.password.required"));
}
return errors;
}
@Override
public void reset(ActionMapping mapping, HttpServletRequest request) {
// Opcional: reset de campos por petición
}
// Getters/Setters
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username != null ? username.trim() : null;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password != null ? password.trim() : null;
}
}
7. Implementación del Action de Struts
Procedemos a implementar el objeto Action de Struts, que será el que procesará la petición de usuario recibida por el ActionServlet (y que coincida con el patrón establecido ".do").
🔎 LoginAction.java
package com.universo.struts1.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import com.universo.struts1.form.LoginForm;
import com.universo.struts1.service.LoginService;
public class LoginAction extends Action {
LoginService service = new LoginService();
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
LoginForm loginForm = (LoginForm) form;
String user = loginForm.getUsername();
String pass = loginForm.getPassword();
// Servicio de validacion de usuario
boolean ok = service.validarUsuario(user, pass);
if (ok) {
request.setAttribute("username", user);
return mapping.findForward("success");
} else {
// Creamos errores globales para el login (credenciales incorrectas)
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_MESSAGE,
new ActionMessage("error.login.invalid"));
// Guardamos errores en request para que <html:errors/> pueda leerlos
saveErrors(request, errors);
return mapping.findForward("failure");
}
}
}
8. Implementación del Servicio de validación de credenciales
Para hacer una prueba mínima de nuestra aplicación Struts, vamos a creanos un Servicio básico de validación de usuario/password. Aquí podría colocarse un acceso a un DAO para comprobar si las credenciales están dadas de alta en un repositorio concreto. Sin embargo, este no es el objetivo de nuestro ejemplo de hoy así que, para simplificar, vamos a establecer una validación mínima: si las credenciales coinciden con unos valores concretos se autoriza el acceso, en caso contrario se bloquea la entrada.
🔎 LoginService.java
package com.universo.struts1.service;
public class LoginService {
// Autorizacion de Usuario
public boolean validarUsuario(String user, String pass) {
// Lógica "mock": usuario demo / password 1234
boolean ok = "demo".equals(user) && "1234".equals(pass);
return ok;
}
}
9. Implementación del formulario de entrada
Procedemos a crear el JSP que va a servir para introducir los datos de entrada en el navegador. En nuestro caso, al tratarse de un login, vamos a pedir que se introduzca el usuario y la contraseña de acceso a una supuesta aplicación.
Fíjate en cómo estamos usando el tag <html:form> para disparar una petición "login.do" cuando el usuario introduzca los datos y lance el <html:submit>. Dichos tags forman parte de la taglib "tags-html" de Struts, librería que hemos importado al principio del JSP con <taglib uri>.
🔎 login.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Login Universo - Struts 1</title>
</head>
<body>
<h2>Login Universo (Struts 1)</h2>
<!-- Muestra TODOS los errores (de campos + globales) -->
<div style="color:red;">
<html:errors/>
</div>
<!-- Formulario de login -->
<html:form action="/login.do" method="post">
<div>
<label>Usuario:</label>
<html:text property="username"/>
<!-- Errores solo del campo username (opcional, extra) -->
<!-- <html:errors property="username"/> -->
</div>
<div>
<label>Contraseña:</label>
<html:password property="password"/>
<!-- Errores solo del campo password (opcional, extra) -->
<!-- <html:errors property="password"/> -->
</div>
<div>
<html:submit value="Entrar"/>
</div>
</html:form>
<p>(Pista: usuario <b>demo</b>, contraseña <b>1234</b>)</p>
</body>
</html>
10. Implementación de la pantalla de éxito
Finalmente, vamos a crearnos también otro JSP que se mostrará por pantalla cuando el usuario realice un login exitoso en la aplicación.
🔎 success.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Bienvenido</title>
</head>
<body>
<h2>Bienvenido, <%= request.getAttribute("username") %> 🎉</h2>
<p>Autenticación correcta.</p>
</body>
</html>
11. Ejecutar Tomcat y realizar el despliegue
A continuación, procedemos a levantar el servidor Tomcat. Para ello, nos posicionamos sobre nuestro Tomcat y pulsamos START.
Ahora nos situamos sobre nuestro proyecto Struts, pulsamos botón derecho del ratón y seleccionamos la opción
RUN AS - RUN ON SERVER.
Seleccionamos la instancia del Tomcat que hemos configurado previamente y pulsamos FINISH. La aplicación empezará a desplegarse. En consola nos debería salir algo como lo siguiente:
dic 10, 2025 10:18:38 A. M. org.apache.catalina.core.StandardEngine startInternal
INFORMACIÓN: Starting Servlet engine: [Apache Tomcat/9.0.113]
dic 10, 2025 10:18:39 A. M. org.apache.jasper.servlet.TldScanner scanJars
INFORMACIÓN: Al menos un JAR, que se ha explorado buscando TLDs, aún no contenía TLDs.
Activar historial de depuración para este historiador para una completa lista de los JARs
que fueron explorados y de los que nos se halló TLDs.
Saltarse JARs no necesarios durante la exploración puede dar lugar a una mejora de tiempo
significativa en el arranque y compilación de JSP .
dic 10, 2025 10:18:39 A. M. org.apache.struts.action.ActionServlet initChain
INFORMACIÓN: Loading chain catalog from jar:file:/C:/Users/alcau/eclipse-workspace/
struts/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/
Struts1Login/WEB-INF/
lib/struts-core-1.3.10.jar!/org/apache/struts/chain/chain-config.xml
dic 10, 2025 10:18:40 A. M. org.apache.coyote.AbstractProtocol start
INFORMACIÓN: Starting ProtocolHandler ["http-nio-8081"]
dic 10, 2025 10:18:40 A. M. org.apache.catalina.startup.Catalina start
INFORMACIÓN: Server startup in [1510] milliseconds
Si todo acaba bien, nuestra aplicación acabará desplegada en el puerto configurado en nuestro servidor Tomcat (en mi caso, se trata del puerto 8081).
12. Acceder a la App desde el navegador
A continuación, podremos acceder al link correspondiente de la app que acabamos de desplegar con nuestro Tomcat:
http://localhost:8081/Struts1Login/
✅ Si ponemos un usuario correcto, la aplicación disparará una petición "login.do" y saltará al JSP de acceso exitoso que hemos implementado anteriormente.
❌ Por contra, si indicamos unas credenciales incorrectas, las validaciones nos mostrarán el error correspondiente y no nos dejarán continuar.
Con todos los pasos indicados, ya deberíamos tener una visión global de cómo se podría implementar una aplicación sencilla siguiendo la estructura del framework Struts.
⚖️ Ventajas y desventajas de Struts en un Dynamic Web Project
Por último, me gustaría comentarte una serie de ventajas e inconvenientes que vienen asociados con la utilización del framework Struts en proyectos no mavenizados.
✅ Ventajas
-
Simplicidad estructural: al no usar Maven, todo es explícito y manual. Esto lo hace ideal para formación o proyectos legacy.
-
Control absoluto: tú decides qué JARs usas y cómo organizas el proyecto.
-
Enseñanza clara del MVC: muy útil para comprender el flujo de peticiones en aplicaciones web Java.
❌ Inconvenientes
-
Gestión manual de dependencias: actualizar o añadir librerías puede ser tedioso.
-
No escalable a gran escala: para proyectos grandes, Maven o Gradle son imprescindibles.
-
Tecnología obsoleta: Struts 1 ya no se mantiene activamente y tiene vulnerabilidades conocidas.
Poco compatible con la nube: Escasa compatibilidad con el mundo Cloud y con pipelines modernos (CI/CD).
🎯 Conclusión
Struts 1 es un clásico del desarrollo Java. Si estás manteniendo un proyecto legacy o si simplemente quieres entender cómo se estructuraban las aplicaciones web antes de la era Spring, crear un Dynamic Web Project clásico es una excelente forma de aprender.
Aunque hoy en día el uso de Struts 1 ha sido reemplazado por frameworks más modernos como Spring MVC o Jakarta Faces, conocerlo sigue siendo valioso para depurar y migrar proyectos antiguos que siguen vivos en producción.
¡Nos vemos en el siguiente post!
Saludos.
Comentarios
Publicar un comentario