1. Generalidades
El PDF del documento está disponible |AQUÍ|.
1.1. Objetivos
Aquí nos proponemos descubrir un método de desarrollo llamado STRUTS. Jakarta Struts es un proyecto de la Apache Software Foundation (www.apache.org) cuyo objetivo es proporcionar un marco estándar para el desarrollo de aplicaciones web en Java que respete la arquitectura denominada MVC (Modelo-Vista-Controlador).
1.2. El modelo MVC
El modelo MVC busca separar las capas de presentación, procesamiento y acceso a los datos. Una aplicación web que siga este modelo tendrá la siguiente arquitectura:
![]() |
A esta arquitectura se le denomina de tres capas o de tres niveles:
- la interfaz de usuario es la V (la vista)
- la lógica de la aplicación es la C (el controlador)
- las fuentes de datos son la M (modelo)
La interfaz de usuario suele ser un navegador web, pero también puede ser una aplicación independiente que, a través de la red, envía solicitudes HTTP al servicio web y da formato a los resultados que este le devuelve. La lógica de la aplicación está formada por los scripts que procesan las solicitudes del usuario. La fuente de datos suele ser una base de datos, pero también pueden ser simples archivos planos, un directorio LDAP, un servicio web remoto, etc. Es recomendable que el desarrollador mantenga una gran independencia entre estas tres entidades, de modo que, si una de ellas cambia, las otras dos no tengan que cambiar, o solo lo hagan mínimamente.
Cuando se busca aplicar este modelo con servlets y páginas JSP, se obtiene la siguiente arquitectura:
![]() |
En el bloque [Logique Applicative], se distingue
- el servlet, que es la puerta de entrada de la aplicación y que también se conoce como controlador
- el bloque [Classes métier], que agrupa las clases Java necesarias para la lógica de la aplicación.
- el bloque [Classes d'accès aux données], que agrupa las clases Java necesarias para obtener los datos que requiere el servlet, a menudo datos persistentes (BD, archivos, servicio WEB, ...)
- el bloque de páginas JSP, que constituye las vistas de la aplicación.
1.3. Un enfoque de desarrollo MVC mediante servlets y páginas JSP
Hemos definido un proceso para el desarrollo de aplicaciones web en Java que sigue el modelo MVC anterior. Lo recordamos aquí.
- Comenzaremos por definir todas las vistas de la aplicación. Estas son las páginas web que se le presentan al usuario. Por lo tanto, nos pondremos en su lugar para diseñar las vistas. Se distinguen tres tipos de vistas:
- el formulario de entrada, cuyo objetivo es obtener información del usuario. Por lo general, cuenta con un botón para enviar la información ingresada al servidor.
- la página de respuesta, que solo sirve para proporcionar información al usuario. A menudo cuenta con un enlace que permite al usuario continuar con la aplicación en otra página.
- la página mixta: el servlet ha enviado al cliente una página que contiene información que él mismo generó. Esa misma página servirá al cliente para proporcionar al servlet otra información.
- Cada vista dará lugar a una página JSP. Para cada una de ellas:
- se definirá el aspecto de la página
- se determinarán cuáles son las partes dinámicas de la misma:
- la información destinada al usuario, que deberá ser proporcionada por el servlet como parámetros a la vista JSP
- los datos ingresados que deberán transmitirse al servlet para su procesamiento. Estos deberán formar parte de un formulario HTML.
- Se pueden esquematizar las entradas y salidas de cada vista
![]() |
- las entradas son los datos que el servlet deberá proporcionar a la página JSP, ya sea en la solicitud (request) o en la sesión (session).
- Las salidas son los datos que la página JSP deberá proporcionar al servlet. Forman parte de un formulario HTML y el servlet los recuperará mediante una operación del tipo request.getparameter(...).
- Escribiremos el código Java/JSP de cada vista. Por lo general, tendrá la siguiente forma:
<%@ page ... %> // importaciones de clases más comunes
<%!
// variables de instancia de la página JSP (=globales)
// solo es necesario si la página JSP tiene métodos que comparten variables (poco frecuente)
...
%>
<%
// recuperación de los datos enviados por el servlet
// ya sea en la solicitud (request) o en la sesión (session)
...
%>
<html>
...
//: aquí se buscará minimizar el código Java
</html>
- Ahora podemos pasar a las primeras pruebas. El método de implementación que se explica a continuación es específico del servidor Tomcat:
- el contexto de la aplicación debe crearse en el archivo server.xml de Tomcat. Podemos comenzar por probar este contexto. Denotemos este contexto como C y la carpeta asociada a él como DC. Crearemos un archivo estático test.html que colocaremos en la carpeta DC. Después de iniciar Tomcat, accederemos con un navegador a la página http://localhost:8080/DC/test.html (URL).
- Cada página JSP se puede probar. Si una página JSP se llama formulaire.jsp, se solicitará con un navegador la página URL http://localhost:8080/DC/formulaire.jsp. La página JSP espera valores del servlet que la llama. Aquí la llamamos directamente, por lo que no recibirá los parámetros esperados. Para que, no obstante, sea posible realizar las pruebas, inicializaremos nosotros mismos en la página JSP los parámetros esperados con constantes. Estas primeras pruebas permiten verificar que las páginas JSP sean sintácticamente correctas.
- A continuación, escribimos el código del servlet. Este cuenta con dos métodos bien diferenciados:
- el método init, que sirve para:
- obtener los parámetros de configuración de la aplicación del archivo web.xml de la misma
- crear, si es necesario, instancias de clases de negocio que se utilizarán posteriormente
- gestionar una posible lista de errores de inicialización que se enviará a los futuros usuarios de la aplicación. Esta gestión de errores puede incluir el envío de un correo electrónico al administrador de la aplicación para notificarle un fallo
- el método doGet o doPost, según la forma en que el servlet reciba los parámetros de sus clientes. Si el servlet maneja varios formularios, es recomendable que cada uno de ellos envíe una información que lo identifique de manera única. Esto se puede lograr mediante un atributo oculto en el formulario del tipo <input type="hidden" name="action" value="...">. El servlet puede comenzar por leer el valor de este parámetro y luego delegar el procesamiento de la solicitud a un método privado interno encargado de manejar este tipo de solicitud.
- Se debe evitar al máximo incluir código de negocio en el servlet. No está diseñado para eso. El servlet es una especie de jefe de equipo (controlador) que recibe solicitudes de sus clientes (usuarios web) y las hace ejecutar por las personas más adecuadas (las clases de negocio). Al escribir el servlet, se determinará la interfaz de las clases de negocio que se deben crear (constructores, métodos). Esto, en caso de que dichas clases de negocio deban crearse. Si ya existen, entonces el servlet debe adaptarse a la interfaz existente.
- Se compilará el código del servlet.
- Se escribirá el esqueleto de las clases de negocio necesarias para el servlet. Por ejemplo, si el servlet utiliza un objeto de tipo proxyArticles y esta clase debe tener un método getCodes que devuelva una lista (ArrayList) de cadenas de caracteres, en un primer momento basta con escribir:
public ArrayList getCodes(){
String[] codes= {"code1","code2","code3"};
ArrayList aCodes=new ArrayList();
for(int i=0;i<codes.length;i++){
aCodes.add(codes[i]);
}
return aCodes;
}
- Ahora podemos pasar a las pruebas del servlet.
- Se debe crear el archivo de configuración web.xml de la aplicación. Debe contener toda la información que espera el método init del servlet (<init-param>). Además, se configura el URL a través del cual se accederá al servlet principal (<servlet-mapping>).
- Todas las clases necesarias (servlet, clases de negocio) se colocan en WEB-INF/classes.
- Todas las bibliotecas de clases (.jar) necesarias se colocan en WEB-INF/lib. Estas bibliotecas pueden contener clases de negocio, controladores JDBC, etc.
- Las vistas JSP se colocan en la raíz de la aplicación o en una carpeta propia. Se hace lo mismo con los demás recursos (HTML, imágenes, audio, videos, etc.).
- Una vez hecho esto, se prueba la aplicación y se corrigen los primeros errores. Al final de esta fase, la arquitectura de la aplicación está operativa. Esta fase de prueba puede resultar complicada, ya que no se cuenta con una herramienta de depuración con Tomcat. Para ello, sería necesario que Tomcat estuviera integrado en una herramienta de desarrollo (JBuilder Developer, Sun One Studio, etc.). Podemos valernos de las instrucciones System.out.println("...."), que escriben en la ventana de Tomcat. Lo primero que hay que verificar es que el método init recupere correctamente todos los datos del archivo web.xml. Para ello, se puede escribir el valor de dichos datos en la ventana de Tomcat. De la misma manera, se verificará que los métodos doGet y doPost recuperen correctamente los parámetros de los distintos formularios HTML de la aplicación.
Se escriben las clases de negocio que necesita el servlet. Por lo general, se trata del desarrollo clásico de una clase Java, que en la mayoría de los casos es independiente de cualquier aplicación web. En primer lugar, se probará fuera de este entorno, por ejemplo, con una aplicación de consola. Una vez escrita una clase de negocio, se puede integrar en la arquitectura de implementación de la aplicación web y probar su correcta integración en ella. Se procederá de esta manera para cada clase de negocio.
1.4. El proceso de desarrollo STRUTS
Los creadores de la metodología STRUTS buscaron definir un método de desarrollo estándar que respete la arquitectura MVC para las aplicaciones web escritas en Java. El proyecto STRUTS tiene dos aspectos:
- el método de desarrollo. Veremos que es bastante similar al descrito anteriormente para los servlets y las páginas JSP
- las herramientas que nos permiten aplicar este método de desarrollo. Se trata de bibliotecas de clases Java que se pueden encontrar en el sitio web de la Fundación Apache (www.apache.org).
1.4.1. El método de desarrollo
La arquitectura MVC utilizada por STRUTS es la siguiente:
![]() |
- El controlador es el corazón de la aplicación. Todas las solicitudes del cliente pasan por él. Se trata de un servlet genérico proporcionado por STRUTS. En algunos casos, puede ser necesario derivarla. Para los casos sencillos, no es necesario. Este servlet genérico toma la información que necesita de un archivo que, por lo general, se llama struts-config.xml.
- Si la solicitud del cliente contiene parámetros de formulario, estos se colocan en un objeto Bean. Se dice que una clase es de tipo Bean si cumple con ciertas reglas de construcción que veremos más adelante. Los objetos Bean creados de esta manera a lo largo del tiempo se almacenan en la sesión o en la solicitud del cliente. Este punto es configurable. No es necesario volver a crearlos si ya se han creado anteriormente.
- En el archivo de configuración struts-config.html, a cada URL que deba ser procesada por un programa (y que, por lo tanto, no corresponda a una vista JSP que se pudiera solicitar directamente) se le asocia cierta información:
- el nombre de la clase de tipo Action encargada de procesar la solicitud. En este caso también, el objeto Action instanciado puede conservarse en la sesión o en la solicitud.
- si la URL solicitada está configurada (como en el caso del envío de un formulario al controlador), se indica el nombre del bean encargado de almacenar la información del formulario.
- Con esta información proporcionada por su archivo de configuración, al recibir una solicitud de URL por parte de un cliente, el controlador es capaz de determinar si hay que crear un bean y cuál. Una vez instanciado, el bean puede verificar si los datos que ha almacenado y que provienen del formulario son válidos o no. El controlador invoca automáticamente un método del bean llamado validate. El bean es creado por el desarrollador, quien incluye en el método validate el código que verifica la validez de los datos del formulario. Si los datos resultan inválidos, el controlador no continuará. Pasará el control a una vista cuyo nombre encontrará en su archivo de configuración. Con esto, el intercambio concluye. Cabe señalar que el desarrollador puede solicitar que no se verifique la validez del formulario. Esto también lo hace en el archivo struts-config.html. En este caso, el controlador no invoca el método validate del bean.
- Si los datos del bean son correctos, o si no hay verificación, o si no hay ningún bean, el controlador pasa el control al objeto de tipo Action asociado al URL. Lo hace solicitando la ejecución del método `execute` de ese objeto, al cual le pasa la referencia del bean que, en su caso, haya construido. Es aquí donde el desarrollador realiza lo que debe hacer: eventualmente deberá recurrir a clases de negocio o a clases de acceso a datos. Al final del procesamiento, el objeto `Action` devuelve al controlador el nombre de la vista que debe enviar como respuesta al cliente.
- El controlador envía esta respuesta. La comunicación con el cliente ha concluido.
Comienza a perfilarse la metodología de desarrollo STRUTS:
- la definición de las vistas. Se distingue entre las vistas que son formularios y las demás.
- Cada vista de formulario da lugar a una definición en el archivo struts-config.xml. En él se define la siguiente información:
- el nombre de la clase Bean que contendrá los datos del formulario, así como la indicación de si los datos deben verificarse o no. Si deben verificarse y resultan inválidos, se debe indicar la vista que se enviará como respuesta al cliente en ese caso.
- el nombre de la clase Action encargada de procesar el formulario.
- el nombre de todas las vistas que podrían enviarse como respuesta al cliente una vez que se haya procesado la solicitud. La clase Action elegirá una de ellas según el resultado del procesamiento.
- Cada vista corresponde a una página JSP. Veremos que en las vistas, especialmente en las vistas de formulario, a veces se utiliza una biblioteca de etiquetas propias de Struts.
- Cada vista de formulario da lugar a una definición en el archivo struts-config.xml. En él se define la siguiente información:
- La creación de las clases JavaBean correspondientes a las vistas de formulario
- la creación de las clases Action encargadas de procesar los formularios
- la creación de las posibles clases de negocio o de acceso a datos
1.4.2. Las herramientas de desarrollo STRUTS
El proyecto STRUTS es uno de los proyectos de la Apache Software Foundation. Varios de estos proyectos se agrupan bajo el nombre de Jakarta y están disponibles en el sitio web de la Apache Software Foundation: http://jakarta.apache.org:

Se recomienda leer esta página. Muchos de estos proyectos son de interés para los desarrolladores de Java. Si seguimos el enlace de Struts que aparece arriba, llegamos a la página de inicio del proyecto:

Aquí también se recomienda leer la página de inicio. Para descargar las bibliotecas Java de Struts, seguimos el enlace «Binaries» que aparece arriba:

Para el entorno Windows, se utilizará el enlace 1.1.zip y 1.1.tar.gz para el entorno Unix (noviembre de 2003). Una vez descomprimido el archivo 1.1.zip, obtenemos la siguiente estructura de directorios:

En esta estructura de directorios se encuentran las bibliotecas de clases Java necesarias para el desarrollo STRUTS. Estas se encuentran en archivos .jar o .war, que son similares a los archivos .zip. Se pueden abrir con las mismas herramientas. La mayoría de las bibliotecas necesarias se encuentran en la carpeta lib mencionada anteriormente:

Además de las bibliotecas de clases .jar, hay archivos .dtd (Document Type Definition) que contienen reglas de validez para los archivos XML. Un archivo XML puede hacer referencia en su contenido a un archivo de este tipo, como el DTD. El programa (denominado analizador) que analiza el contenido del archivo XML utilizará las reglas de validez que se encuentran en el archivo DTD al que se hace referencia para determinar si el archivo XML es sintácticamente correcto. Así, por ejemplo, el archivo struts-config_1_1.dtd establece las reglas de construcción del archivo de configuración struts-config.xml para la versión 1.1 de Struts.
Veamos ahora dónde colocar los distintos elementos del árbol de Struts para implementar una aplicación Struts en el servidor Tomcat.
1.5. Implementación de una aplicación Struts
Una aplicación Struts es una aplicación web como cualquier otra. Por lo tanto, sigue las reglas de implementación del contenedor en el que se ejecuta. En este caso, una aplicación, a la que llamaremos strutspersonne, se ejecutará en un servidor Tomcat versión 4.x. En el anexo se incluye el procedimiento de implementación para Tomcat versión 5.x. Aquí seguimos las reglas de implementación de Tomcat 4.x:
- Definimos el contexto «strutspersonne» en el archivo de configuración server.xml de Tomcat:
Una vez hecho esto, reiniciamos Tomcat si es necesario para que reconozca el nuevo contexto. Podemos verificar la validez del contexto solicitando la página URL http://localhost:8080/strutspersonne:

Si no aparece una página de error, significa que el contexto es correcto.
- Creamos, en la carpeta física asociada al contexto strutspersonne, la subcarpeta WEB-INF.
- En la carpeta WEB-INF de la aplicación, definimos el archivo de configuración web.xml de la aplicación:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<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>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
- La clase del controlador (servlet) de la aplicación es una clase predefinida de Struts, llamada ActionServlet. Se encuentra en el archivo struts.jar. Para que Tomcat pueda encontrar esta clase, colocaremos struts.jar en la carpeta <tomcat>\common\lib, que es una de las carpetas que Tomcat revisa cuando busca clases. De hecho, colocaremos allí todos los archivos .jar que se encuentren en la carpeta <struts>\lib, donde <struts> es la carpeta raíz del árbol de directorios de Struts.

- También se colocarán los archivos struts-el.jar y jstl.jar que se encuentran en <struts>\contrib\struts-el\lib:

- Aquí tenemos acceso al servidor web. No siempre es así. Si se implementa una aplicación web/Java en un contenedor web que no se administra uno mismo, es preferible que la aplicación traiga consigo todas las bibliotecas que necesita. Estas deben colocarse en la carpeta WEB-INF/lib, que hay que crear.
- Hemos indicado que el controlador necesita cierta información que normalmente encuentra en un archivo struts-config.xml ubicado en la misma carpeta que web.xml. De hecho, el nombre de este archivo se puede configurar. Es el parámetro config, mencionado anteriormente, el que establece este nombre.
- La etiqueta <servlet-mapping> indica que se accederá al controlador a través de todos los archivos URL que terminen con el sufijo .do. Esta asociación es requerida por Struts. Posteriormente, estas URL serán filtradas por el controlador, el cual solo aceptará las URL declaradas en su archivo de configuración struts-config.xml
Por el momento, nuestro archivo web.xml es suficiente.
- Vamos a solicitar el URL /main.do a la aplicación strutspersonne. Según el archivo web.xml anterior, este URL se transmitirá, por lo tanto, al servlet org.apache.struts.action. Se instanciará la clase ActionServlet y se llamará a su método init. Este intenta leer el archivo de configuración definido por el parámetro config. Por lo tanto, este debe existir. Creamos el siguiente archivo struts-config.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<action-mappings>
<action
path="/main"
parameter="/main.html"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
</struts-config>
Cabe señalar que el archivo DTD de struts-config.xml no es el mismo que el del archivo web.xml, lo que indica que no tienen la misma estructura. Para cada URL que el controlador debe gestionar, debemos definir una etiqueta <action>. Esta sirve para indicarle al controlador qué debe hacer cuando se le solicita este URL. Aquí indicamos los siguientes elementos:
- path="/main": define el nombre de la URL configurada por la etiqueta <action>. El sufijo .do es implícito.
- type="org.apache.struts.actions.ForwardAction": define el nombre de la clase Action que debe procesar la solicitud. Aquí se utiliza una clase Action predefinida en Struts. Esta no realiza ninguna acción por sí misma, sino que reenvía la solicitud del cliente a la URL indicada en el atributo parameter.
- parameter="/main.html": el nombre del URL al que se debe reenviar la solicitud. En este caso, se trata de un archivo HTML estático.
En resumen, cuando el usuario solicite el URL /main.do, obtendrá el URL /main.html.
- El archivo main.html será el siguiente:
<html>
<head>
<title>Application strutspersonne</title>
</head>
<body>
Application strutspersonne active ....
</body>
</html>
Este archivo se encuentra en la carpeta de la aplicación strutspersonne/vues:

Se puede solicitar directamente con el código URL http://localhost:8080/strutspersonne/main.html:

En este caso, el controlador Struts de la aplicación no intervino, ya que solo interviene si se solicita el URL de tipo *.do. Sin embargo, aquí se solicitó el URL /vues/main.html.
- El archivo struts-config.xml creado anteriormente debe colocarse en la misma carpeta WEB-INF que el archivo web.xml:

- Ahora verificaremos que el controlador de la aplicación strutspersonne funcione correctamente solicitando el archivo URL /main.do después de haber reiniciado Tomcat, si es necesario.

Aquí intervino el controlador Struts, ya que solicitamos un URL de tipo *.do. Efectivamente, obtuvimos la página esperada (main.html). Así pues, contamos con los elementos básicos del funcionamiento de nuestra aplicación: el contexto strutspersonne, los archivos de configuración web.xml y struts-config.xml, y las bibliotecas de Struts.
¿Qué habría pasado si hubiéramos solicitado un URL de tipo /toto.do? Según el archivo web.xml de la aplicación strutspersonne, se invoca entonces al controlador Struts para procesarlo. Este consulta entonces su archivo de configuración struts-config.html y no encuentra ninguna configuración para el URL /toto. ¿Qué hace entonces? Probemos:

Obtenemos una página de errores, lo cual parece normal. Ahora podemos comenzar a escribir una aplicación.



