Está en la página 1de 327

Struts

2 edicin













Struts
2 edicin
Antonio J. Martn Sierra





A mi sobrino Hugo.


NDICE
PRLOGO ............................................................................................................. 13
CAPTULO 1. LA ARQUITECTURA MODELO VISTA
CONTROLADOR .............................................................................................. 19
1.1 EL PATRN MVC ............................................................................................... 20
1.1.1 EL CONTROLADOR ......................................................................................... 21
1.1.2 LA VISTA ....................................................................................................... 22
1.1.3 EL MODELO ................................................................................................... 22
1.2 FUNCIONAMIENTO DE UNA APLICACIN MVC ....................................... 23
CAPTULO 2. EL FRAMEWORK STRUTS .................................................... 35
2.1 FUNDAMENTOS DE STRUTS .......................................................................... 36
2.2 COMPONENTES DE STRUTS ........................................................................... 37
2.2.1 ARCHIVOS DE CONFIGURACIN ...................................................................... 37
2.2.2 EL API DE STRUTS ......................................................................................... 39
2.2.3 LIBRERAS DE ACCIONES J SP ......................................................................... 41
2.3 FUNCIONAMIENTO DE UNA APLICACIN STRUTS .................................. 42
CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS ...... 45
3.1 DESCARGA E INSTALACIN DEL FRAMEWORK STRUTS ....................... 45
3.2 APLICACIN PRCTICA PARA VALIDACIN Y REGISTRO DE
USUARIOS ......................................................................................................... 47
3.2.1 FUNCIONAMIENTO DE LA APLICACIN ............................................................ 48
3.2.2 ESQUEMA DE LA APLICACIN ......................................................................... 48
3.2.3 CONSTRUCCIN DE LA APLICACIN ............................................................... 50
8 STRUTS RA-MA

3.2.3.1 Estructura de una aplicacin Web Struts ............................................... 50
3.2.3.2 Registro del servlet ActionServlet ......................................................... 52
3.2.3.3 Captura de datos de usuario: Las clases ValidacionForm y
RegistroForm ........................................................................................ 53
3.2.3.4 Implementacin del Modelo .................................................................. 56
3.2.3.5 Procesamiento de peticiones: Las clases ValidarAction y
RegistrarAction ...................................................................................... 59
3.2.3.6 Objetos forward globales ....................................................................... 64
3.2.3.7 Las pginas de la vista ........................................................................... 65
CAPTULO 4. NALISIS DEL API DE STRUTS ............................................ 87
4.1 PROCESAMIENTO DE UNA PETICIN: CLASES ACTIONSERVLET
Y REQUESTPROCESSOR .................................................................................. 87
4.2 CLASES DE ACCIN ......................................................................................... 91
4.2.1 CLASE DISPATCHACTION ............................................................................... 92
4.2.2 CLASE LOOKUPDISPATCHACTION ............................................................... 106
4.2.3 CLASE MAPPINGDISPATCHACTION .............................................................. 112
4.2.4 CLASE ACTIONFORM ................................................................................... 125
4.2.4.1 Ciclo de vida de un ActionForm .......................................................... 125
4.2.5 ACTIONERRORS Y ACTIONMESSAGE ........................................................... 128
4.3 CONTROL DE EXCEPCIONES EN STRUTS ................................................. 133
4.3.1 GESTIN DECLARATIVA DE EXCEPCIONES .................................................... 134
4.3.2 IMPLEMENTACIN DE LA GESTIN DECLARATIVA DE EXCEPCIONES ............. 135
4.3.3 CLASES PERSONALIZADAS PARA LA GESTIN DE EXCEPCIONES .................... 139
CAPTULO 5. LIBRERAS DE ACCIONES JSP DE STRUTS .................... 143
5.1 LIBRERA BEAN .............................................................................................. 143
5.1.1 WRITE ........................................................................................................... 144
5.1.2 PARAMETER .................................................................................................. 145
5.1.3 COOKIE ......................................................................................................... 145
5.1.4 HEADER ........................................................................................................ 146
5.1.5 MESSAGE ...................................................................................................... 146
5.1.6 DEFINE ......................................................................................................... 147
5.1.7 PAGE ............................................................................................................ 149
5.1.8 SIZE .............................................................................................................. 149
5.2 LIBRERA LOGIC ............................................................................................. 150
5.2.1 EQUAL .......................................................................................................... 151
5.2.2 NOTEQUAL ................................................................................................... 154
RA-MA NDICE 9



5.2.3 GREATEREQUAL, LESSEQUAL, GREATERTHAN Y LESSTHAN ........................ 154
5.2.4 MATCH ......................................................................................................... 154
5.2.5 NOMATCH .................................................................................................... 155
5.2.6 FORWARD ..................................................................................................... 155
5.2.7 REDIRECT ..................................................................................................... 155
5.2.8 ITERATE ........................................................................................................ 157
CAPTULO 6. VALIDACIN DE DATOS DE USUARIO ............................ 171
6.1 COMPONENTES DE UN VALIDADOR ......................................................... 171
6.1.1 PLUG-IN VALIDATOR .................................................................................... 172
6.1.2 ARCHIVOS DE CONFIGURACIN .................................................................... 172
6.1.2.1 validator-rules.xml ............................................................................... 173
6.1.2.2 validation.xml ...................................................................................... 174
6.1.3 CLASE VALIDATORFORM ............................................................................. 175
6.1.4 ARCHIVO APPLICATIONRESOURCE.PROPERTIES ........................................... 176
6.2 UTILIZACIN DE VALIDADORES ............................................................... 177
6.2.1 CREACIN DE LA CLASE VALIDATORFORM .................................................. 178
6.2.2 DEFINICIN DE LOS CRITERIOS DE VALIDACIN ........................................... 178
6.2.3 HABILITACIN DE LA VALIDACIN EN CLIENTE ............................................ 180
6.2.4 MENSAJ ES DE ERROR .................................................................................... 182
6.3 VALIDADORES PREDEFINIDOS DE STRUTS ............................................. 183
6.3.1 MINLENGTH .................................................................................................. 183
6.3.2 MAXLENGTH ................................................................................................. 184
6.3.3 BYTE, SHORT, INTEGER, LONG, FLOAT Y DOUBLE .......................................... 185
6.3.4 INTRANGE .................................................................................................... 185
6.3.5 FLOATRANGE Y DOUBLERANGE ................................................................... 186
6.3.6 DATE ............................................................................................................ 186
6.3.7 MASK ............................................................................................................ 187
6.3.8 EMAIL ........................................................................................................... 187
6.4 MENSAJ ES DE ERROR PERSONALIZADOS ................................................ 187
6.5 VALIDACIONES PERSONALIZADAS ........................................................... 193
6.5.1 SOBRESCRITURA DEL MTODO VALIDATE() .................................................. 193
6.5.2 CREACIN DE VALIDADORES PERSONALIZADOS ........................................... 195
6.5.2.1 Implementacin del mtodo de validacin .......................................... 196
6.5.2.2 Registro del validador .......................................................................... 198
6.5.2.3 Mensajes de error ................................................................................. 200
6.5.2.4 Utilizacin del validador ...................................................................... 200
10 STRUTS RA-MA

CAPTULO 7. UTILIZACIN DE PLANTILLAS ......................................... 201
7.1 CONFIGURACIN DE LA APLICACIN PARA EL USO
DE PLANTILLAS .......................................................................................... 202
7.2 CREACIN DE UNA APLICACIN STRUTS
BASADA EN PLANTILLAS ......................................................................... 202
7.2.1 CREACIN DE LA PLANTILLA ........................................................................ 203
7.2.2 CREACIN DE PIEZAS DE CONTENIDO ........................................................... 205
7.2.3 CREACIN DE LAS PGINAS DE APLICACIN ................................................. 207
7.2.4 DECLARACIN DE LA PLANTILLA ................................................................. 207
7.2.5 INCLUSIN DE PGINAS DE CONTENIDO ....................................................... 208
7.3 DEFINICIONES ................................................................................................. 209
7.3.1 CREACIN DE UNA DEFINICIN .................................................................... 210
7.3.1.1 Definiciones base ................................................................................. 210
7.3.1.2 Definiciones derivadas ......................................................................... 211
7.3.2 PGINAS DE APLICACIN .............................................................................. 212
CAPTULO 8. STRUTS 2 .................................................................................. 223
8.1 COMPONENTES DE STRUTS 2 ...................................................................... 224
8.1.1 FILTERDISPATCHER ..................................................................................... 224
8.1.2 INTERCEPTORES ........................................................................................... 225
8.1.3 ACTION ........................................................................................................ 226
8.1.4 LIBRERAS DE ACCIONES .............................................................................. 227
8.1.5 ARCHIVO DE CONFIGURACIN STRUTS.XML ................................................. 227
8.1.5.1 Paquetes ............................................................................................... 228
8.1.5.2 Herencia de paquetes ........................................................................... 229
8.1.5.3 Modularidad de ficheros de configuracin .......................................... 237
8.2 BENEFICIOS DEL USO DE STRUTS 2 ........................................................... 237
8.3 CREACIN DE UNA APLICACIN DE EJ EMPLO DE STRUTS 2 ............. 238
8.3.1 DESCARGA DEL PAQUETE DE DISTRIBUCIN DE STRUTS 2 ............................ 238
8.3.2 REQUERIMIENTOS SOFTWARE ...................................................................... 239
8.3.3 DESCRIPCIN DE LA APLICACIN ................................................................. 239
8.3.4 ESTRUCTURA DE DIRECTORIOS DE LA APLICACIN ....................................... 240
8.3.5 REGISTRO DE FILTERDISPATCHER ................................................................ 241
8.3.6 IMPLEMENTACIN DE LA CLASE DE ACCIN ................................................. 242
8.3.7 REGISTRO DE LA CLASE DE ACCIN .............................................................. 243
8.3.8 REGLAS DE NAVEGACIN ............................................................................. 243
8.3.8.1 Accin por defecto ............................................................................... 244
8.3.9 VISTAS ......................................................................................................... 244
RA-MA NDICE 11



8.4 UTILIZACIN DE INTERCEPTORES ............................................................ 245
8.4.1 DECLARACIN DEL INTERCEPTOR ................................................................ 246
8.4.2 ASIGNACIN DE UN INTERCEPTOR A UNA ACCIN ........................................ 248
8.4.3 INYECCIN DE DEPENDENCIA ....................................................................... 248
8.4.4 INTERCEPTORES PERSONALIZADOS .............................................................. 258
8.4.4.1 El mtodo intercept() ........................................................................... 258
8.5 LA LIBRERA DE ACCIONES STRUTS-TAGS ............................................. 267
8.5.1 EL STACK DE OBJ ETOS .................................................................................. 267
8.5.2 ACCIONES DE MANIPULACIN DE DATOS ...................................................... 269
8.5.2.1 bean ...................................................................................................... 269
8.5.2.2 param ................................................................................................... 269
8.5.2.3 property ................................................................................................ 269
8.5.2.4 push ...................................................................................................... 270
8.5.2.5 set ......................................................................................................... 270
8.5.3 ACCIONES DE CONTROL ................................................................................ 270
8.5.3.1 if ........................................................................................................... 271
8.5.3.2 iterator .................................................................................................. 271
8.5.4 ACCIONES UI ............................................................................................... 272
8.5.4.1 form ..................................................................................................... 273
8.5.4.2 textfield ................................................................................................ 273
8.5.4.3 password .............................................................................................. 275
8.5.4.4 textarea ................................................................................................. 275
8.5.4.5 submit .................................................................................................. 275
8.5.4.6 radio ..................................................................................................... 277
8.5.4.7 checkbox .............................................................................................. 279
8.5.4.8 CheckboxList ....................................................................................... 279
8.5.4.9 select .................................................................................................... 279
8.5.4.10 actionerror .......................................................................................... 286
8.6 VALIDADORES ................................................................................................ 286
8.6.1 VALIDADORES PREDEFINIDOS ...................................................................... 286
8.6.2 UTILIZACIN DE VALIDADORES EN UNA APLICACIN ................................... 288
8.6.3 VALIDACIN MEDIANTE ANOTACIONES ....................................................... 291
8.6.3.1 Tipos de anotaciones de validacin ..................................................... 294
APNDICE A. EL LENGUAJE DE EXPRESIONES DE JSP ...................... 305
EXPRESIONES EL .................................................................................................. 306
ACCESO A VARIABLES DE MBITO ................................................................. 307
12 STRUTS RA-MA

OBJ ETOS IMPLCITOS EL .................................................................................... 308
OPERADORES EL .................................................................................................. 310
APNDICE B. LA LIBRERA DE ACCIONES ESTNDAR
DE JSP (JSTL) ............................................................................................. 313
INSTALACIN DE JSTL ........................................................................................ 313
UTILIZACIN DE ACCIONES J STL .................................................................... 314
ANLISIS DE LAS PRINCIPALES ACCIONES JSTL ......................................... 314
ACCIONES GENRICAS .......................................................................................... 315
out .................................................................................................................... 315
set ..................................................................................................................... 315
remove ............................................................................................................. 316
catch ................................................................................................................. 316
redirect ............................................................................................................. 317
CONTROL DE FLUJ O ............................................................................................... 317
if ....................................................................................................................... 317
choose .............................................................................................................. 318
foreach ............................................................................................................. 319
fortokens .......................................................................................................... 319
NDICE ALFABTICO ..................................................................................... 321


PRLOGO
El rpido crecimiento que ha experimentado en los ltimos aos el uso de
aplicaciones Web ha ido paralelo con el aumento en la demanda de nuevas
funcionalidades que los usuarios solicitan a estas aplicaciones.
Esto ha supuesto al mismo tiempo un incremento en la complejidad de los
desarrollos, provocando la proliferacin de lenguajes, herramientas y tecnologas
orientadas a facilitar el trabajo de los programadores.
Una de esas tecnologas es Struts. Struts se enmarca dentro del mbito
del desarrollo de aplicaciones para Internet bajo arquitectura J avaEE, si bien, no se
trata de un elemento ms de dicha arquitectura sino de un marco de trabajo que
ayuda a los programadores en la creacin de aplicaciones en este entorno,
reduciendo la complejidad y el tiempo de los desarrollos y, sobre todo, hacindolos
mucho ms robustos y fciles de mantener.
Struts fue lanzado por primera vez al mercado en el ao 2002 y desde ese
mismo momento tuvo una enorme aceptacin en la comunidad de desarrolladores,
hasta el punto que hoy en da es, con diferencia, el framework ms utilizado en la
construccin de aplicaciones J avaEE.
En los ltimos dos aos han ido apareciendo otros framework J avaEE que
estn teniendo bastante aceptacin, como Spring o J ava Server Faces (J SF). Pero
este hecho, lejos de perjudicar a Struts, ha propiciado su evolucin y su adaptacin
a los requerimientos de las aplicaciones modernas. Adems, la utilizacin de Struts
no es incompatible con estos nuevos frameworks, siendo posible su integracin con
los anteriormente mencionados de cara a aumentar la potencia de los desarrollos.
14 STRUTS RA-MA

OBJETIVO DEL LIBRO
El objetivo que se pretende con este libro es presentar al lector todos los
elementos que componen el framework Struts y guiarle en el desarrollo de las
aplicaciones, para lo cual se presentan una serie de prcticas que servirn para
aclarar los conceptos tratados y mostrarle la forma en la que los distintos
componentes deben ser utilizados en los desarrollos.
As pues, al finalizar el estudio de este libro el lector estar capacitado para
construir aplicaciones Web bajo arquitectura J avaEE, totalmente estructuradas y
robustas, utilizando toda la potencia que le ofrece Struts, incluidas las nuevas
prestaciones y metodologa de trabajo que se incluye en la ltima versin Struts 2.
A QUIN VA DIRIGIDO
Para poder comprender y utilizar los conceptos que se exponen en este
libro es necesario tener conocimientos de programacin en J ava y estar
familiarizado con el uso de las principales tecnologas J avaEE, como son el API
Servlet y las pginas J SP.
Este libro ser por tanto de gran utilidad a aquellos programadores JavaEE
que se vayan a enfrentar al reto de desarrollar grandes aplicaciones empresariales
en este entorno, pues es en estas circunstancias donde la utilizacin de un
framework con las prestaciones de Struts se hace ms que necesaria.
El libro puede ser utilizado tambin por estudiantes y, en general, por
cualquier conocedor de la plataforma J avaEE que desee ampliar sus conocimientos
adentrndose en el anlisis de las posibilidades que ofrece Struts.
Por su enfoque didctico y prctico, este libro puede ser utilizado como
manual de estudio en cursos de programacin en J ava sobre plataforma J avaEE
donde se incluya un mdulo de Struts, siendo de gran ayuda los ejemplos y
prcticas que se incluyen.



RA-MA PRLOGO 15



ESTRUCTURA DEL LIBRO
El libro est organizado en ocho Captulos y dos apndices.
Al ser el principio sobre el que est construido el framework Struts, el
Captulo 1 nos presenta la arquitectura Modelo Vista Controlador, analizando los
roles desempeados por cada capa y las ventajas que este patrn nos ofrece frente
al desarrollo tradicional.
El Captulo 2 nos introduce de lleno en el framework Struts, presentando
los distintos componentes que lo integran y el funcionamiento general de la
arquitectura.
Ser durante el Captulo 3 cuando se ponga en prctica la utilizacin de
Struts con el desarrollo de una aplicacin de ejemplo, aplicacin que nos servir
para comprender la funcionalidad de cada uno de los componentes presentados en
el Captulo anterior y la forma en que interactan entre s.
En los Captulos 4 y 5 analizaremos en detalle los dos grandes tipos de
piezas que componen este framework: el API de Struts y las libreras de acciones
J SP, respectivamente.
Los Captulos 6 y 7 servirn para profundizar en dos de las caractersticas
avanzadas ms interesantes de Struts. En concreto, el Captulo 6 aborda el estudio
de los validadores, con cuya ayuda podremos evitar la codificacin de grandes
cantidades de cdigo dedicadas nicamente a comprobar los datos suministrados
por el usuario, mientras que el Captulo 7 analiza el uso de las plantillas (tiles) para
la reutilizacin de cdigo en las vistas de una aplicacin.
El Captulo 8 nos presenta las caractersticas de la nueva versin del
framework: Struts 2, analizando la arquitectura planteada para el desarrollo de las
aplicaciones, as como la funcionalidad, utilizacin y configuracin de los nuevos
componentes del framework.
Por ltimo, los Apndices A y B nos presentan dos elementos que, sin
formar parte de framework Struts, se complementan perfectamente con l y ayudan
a mejorar los desarrollos; concretamente se trata del lenguaje de expresiones para
J SP, ms conocido como lenguaje EL, y de la librera de acciones estndares J SP,
conocida tambin como librera J STL.
16 STRUTS RA-MA

MATERIAL ADICIONAL
Los ejercicios prcticos desarrolladas en los distintos Captulos del libro
pueden ser descargados desde la Web de Ra-Ma. Estas aplicaciones han sido
creadas con el entorno de desarrollo J ava NetBeans 6.8, de modo que si el lector
cuenta con dicho entorno instalado en su mquina podr abrir directamente los
proyectos y probar su funcionamiento. No obstante, cada proyecto incluye una
carpeta con los cdigos fuente a fin de que puedan ser utilizados en otro entorno.
CONVENCIONES UTILIZADAS
Se han utilizado las siguientes convenciones a lo largo del libro:
Uso de negrita para resaltar ciertas definiciones o puntos
importantes a tener en cuenta.
Utilizacin de cursiva para mtodos y propiedades de objetos y
atributos de etiquetas, as como para presentar el formato de
utilizacin de algn elemento de cdigo.
Empleo de estilo cour i er para listados, tanto de cdigo J ava
como de etiquetado XHTML/J SP. Para destacar los comentarios
dentro del cdigo se utilizar el tipo cour i er en cur si va,
mientras que para resaltar las instrucciones importantes se
emplear cour i er en negr i t a.
AGRADECIMIENTOS
Quiero mostrar mi agradecimiento al equipo de Ra-Ma, que ha hecho
posible que este libro salga a la luz, en especial a Luis San J os y J ess Ramrez.
Tambin quiero agradecer a J uan Garca Sanz, Gerente de Formacin de
logos, a J uan de Dios Izquierdo, J efe de Estudios de CICE y a Ramn Egido,
director de Syncrom, su apoyo y esfuerzo en la difusin de mis libros.

RA-MA PRLOGO 17



DIRECCIN DE CONTACTO
Espero que este libro resulte de utilidad al lector, y pueda ayudarle a
integrar el framework Struts en sus desarrollos y a poder sacar partido a todas las
ventajas que ste ofrece.
Si desea realizar alguna consulta u observacin, puede contactar conmigo a
travs de la siguiente direccin de correo electrnico:
ajms66@gmail.com



1Captulo 1
LA ARQUITECTURA MODELO VISTA
CONTROLADOR
Las aplicaciones Web estn organizadas siguiendo una arquitectura de tres
capas, donde la capa cliente, implementada mediante pginas Web, tiene como
misin la captura de datos de usuario y su envo a la capa intermedia, as como la
presentacin de resultados procedentes de sta. Es la capa intermedia la que
constituye el verdadero ncleo de la aplicacin Web, encargndose del
procesamiento de los datos de usuario y de la generacin y envo de las respuestas
a la capa cliente. Durante este proceso, la capa intermedia deber interaccionar con
la capa de datos para el almacenamiento y recuperacin de informacin manejada
por la aplicacin (figura 1).






Fig. 1. Esquema de capas de una aplicacin Web
20 STRUTS RA-MA

Son muchas las tecnologas y lenguajes que los programadores tienen a su
disposicin para acometer el desarrollo de la capa intermedia de una aplicacin
Web (J ava/J avaEE, PHP, ASP.NET, etc.). No obstante, de cara a afrontar con xito
su implementacin, se hace necesario establecer un modelo o esquema que permita
estructurar esta capa en una serie de bloques o componentes, de modo que cada
uno de estos bloques tenga unas funciones bien definidas dentro de la aplicacin y
pueda desarrollarse de manera independiente al resto.
Uno de estos esquemas y, con toda seguridad, el ms utilizado por los
desarrolladores que utilizan J avaEE es la arquitectura Modelo Vista Controlador
(MVC), la cual proporciona una clara separacin entre las distintas
responsabilidades de la aplicacin.
1.1 EL PATRN MVC
Cuando hablamos de arquitectura Modelo Vista Controlador nos referimos
a un patrn de diseo que especifica cmo debe ser estructurada una aplicacin, las
capas que van a componer la misma y la funcionalidad de cada una.
Segn este patrn, la capa intermedia de una aplicacin Web puede ser
dividida en tres grandes bloques funcionales:
Controlador.
Vista.
Modelo.
En la figura 2 se muestra esta arquitectura para el caso de una aplicacin
desarrollada con tecnologas J avaEE. En ella podemos ver cmo se relacionan
estos tres bloques funcionales entre s, su interaccin con el resto de las capas de la
aplicacin y la tecnologa con la que estn implementados.
Seguidamente vamos a analizar detalladamente cada uno de estos bloques,
presentando las caractersticas de cada uno de ellos, funcionalidades y tipo de
tecnologa empleada en el desarrollo de cada uno de ellos.



RA-MA CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 21







Fig. 2. Esquema de una aplicacin MVC
1.1.1 El Controlador
Se puede decir que el Controlador es el cerebro de la aplicacin. Todas
las peticiones a la capa intermedia que se realicen desde el cliente son dirigidas
al Controlador, cuya misin es determinar las acciones a realizar para cada una de
estas peticiones e invocar al resto de los componentes de la aplicacin (Modelo y
Vista) para que realicen las acciones requeridas en cada caso, encargndose
tambin de la coordinacin de todo el proceso.
Por ejemplo, en el caso de que una peticin requiera enviar como respuesta
al cliente determinada informacin existente en una base de datos, el Controlador
solicitar los datos necesarios al modelo y, una vez recibidos, se los proporcionar
a la Vista para que sta les aplique el formato de presentacin correspondiente y
enve la respuesta al cliente.
La centralizacin del flujo de peticiones en el Controlador proporciona
varias ventajas al programador, entre ellas:
Hace que el desarrollo sea ms sencillo y limpio.
Facilita el posterior mantenimiento de la aplicacin hacindola ms
escalable.
Facilita la deteccin de errores en el cdigo.
En aplicaciones J avaEE el Controlador es implementado mediante un
servlet central que, dependiendo de la cantidad de tipos de peticiones que debe
gestionar, puede apoyarse en otros servlets auxiliares para procesar cada peticin
(figura 3).
BD
Controlador (Servlet)
Vista
(JSP)
Modelo
(Clases,
EJB)
Browser
BD
Controlador (Servlet)
Vista
(JSP)
Modelo
(Clases,
EJB)
Browser
22 STRUTS RA-MA








Fig. 3. Despacho de la gestin de peticiones entre distintos servlets
1.1.2 La Vista
Tal y como se puede deducir de su nombre, la Vista es la encargada de
generar las respuestas (habitualmente XHTML) que deben ser enviadas al cliente.
Cuando esta respuesta tiene que incluir datos proporcionados por el Controlador, el
cdigo XHTML de la pgina no ser fijo si no que deber ser generado de forma
dinmica, por lo que su implementacin correr a cargo de una pgina JSP.
Las pginas J SP resultan mucho ms adecuadas para la generacin de las
vistas que los servlets pues, al ser documentos de texto, resulta sencilla la inclusin
de bloques estticos XHTML y pueden ser fcilmente mantenibles por diseadores
Web con escasos conocimientos de programacin.
Cuando la informacin que se va a enviar es esttica, es decir, no depende
de datos extrados de un almacenamiento externo, podr ser implementada por una
pgina o documento XHTML.
1.1.3 El Modelo
En la arquitectura MVC la lgica de negocio de la aplicacin, incluyendo
el acceso a los datos y su manipulacin, est encapsulada dentro del modelo. El
Modelo lo forman una serie de componentes de negocio independientes del
Controlador y la Vista, permitiendo as su reutilizacin y el desacoplamiento entre
las capas.
Servlet
principal
Servlet 1
Servlet 2
Servlet 3
peticin 1
peticin 2
peticin 3
g
e
s
t
i

n

p
e
t
i
c
i

n

1
gestin
peticin 2
g
e
s
t
i

n

p
e
t
i
c
i

n

3
RA-MA CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 23

En una aplicacin J avaEE el modelo puede ser implementado mediante
clases estndar J ava o a travs de Enterprise JavaBeans.
1.2 FUNCIONAMIENTO DE UNA APLICACIN MVC
Una vez analizados los distintos bloques MVC resulta sencillo comprender
el funcionamiento de este tipo de aplicaciones. Para ello, analizaremos los procesos
que tienen lugar en la capa intermedia desde que llega la peticin procedente de la
capa cliente hasta que se genera la respuesta:
Captura de la peticin en el Controlador. Como hemos dicho,
todas las peticiones que se reciben en la aplicacin son
centralizadas en el Controlador, el cual a partir de la URL de la
solicitud determina el tipo de la operacin que quiere llevar a cabo
el cliente. Normalmente, esto se hace analizando el valor de algn
parmetro que se enva anexado a la URL de la peticin y que se
utiliza con esta finalidad:
url?operacion=validar
Otra opcin es utilizar la propia URL para codificar la operacin a
realizar, en este caso, se utilizara el path info de la direccin como
indicativo del tipo de accin. En este sentido, la figura 4 nos
muestra las distintas partes en las que se puede descomponer la
URL completa asociada a una peticin.



Fig. 4. Partes de una URL
Por ejemplo, si en un servidor de nombre de dominio
www.libros.com tenemos desplegada una aplicacin llamada
biblioteca, cuyo Controlador es un servlet que tiene como url
pattern el valor /control, la URL asociada a la operacin de
validar podra ser:
www.libros.com/biblioteca/control/validar
http://www.miservidor.com/aplicacion/url_servlet /info
servidor
url de la aplicacin
(context path)
url del servlet
(servlet path)
informacin adicional
(pathinfo)
24 STRUTS RA-MA

Mientras que otra operacin, por ejemplo registrar, tendra como
URL:
www.libros.com/biblioteca/control/registrar
Todas estas peticiones provocarn la ejecucin del servlet
controlador, el cual utilizar el mtodo getPathInfo() del API
servlet para determinar la operacin a realizar.
Procesamiento de la peticin. Una vez que el Controlador
determina la operacin a realizar, procede a ejecutar las acciones
pertinentes, invocando para ello a los diferentes mtodos expuestos
por el Modelo.
Dependiendo de las acciones a realizar (por ejemplo, un alta de un
usuario en un sistema), el Modelo necesitar manejar los datos
enviados por el cliente en la peticin, datos que le sern
proporcionados por el Controlador. De la misma manera, los
resultados generados por el Modelo (por ejemplo, la informacin
resultante de una bsqueda) sern entregados directamente al
Controlador.
Para facilitar este intercambio de datos entre Controlador y Modelo
y, posteriormente, entre Controlador y Vista, las aplicaciones
MVC suelen hacer uso de J avaBeans. Un J avaBean no es ms que
una clase que encapsula un conjunto de datos con mtodos de tipo
set/get para proporcionar un acceso a los mismos desde el exterior.
El siguiente listado representa un J avaBean de ejemplo que
permite encapsular una serie de datos asociados a una persona:
publ i c cl ass Per sona{
pr i vat e St r i ng nombr e;
pr i vat e St r i ng apel l i do;
pr i vat e i nt edad;

publ i c voi d set Nombr e( St r i ng nombr e) {
t hi s. nombr e=nombr e;
}
publ i c St r i ng get nombr e( ) {
r et ur n t hi s. nombr e;
}
publ i c voi d set Apel l i do( St r i ng apel l i do) {
RA-MA CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 25

t hi s. apel l i do=apel l i do;
}
publ i c St r i ng get Apel l i do( ) {
r et ur n t hi s. apel l i do;
}
publ i c voi d set Edad( i nt edad) {
t hi s. edad=edad;
}
publ i c i nt get Edad( ) {
r et ur n t hi s. edad;
}
}
Generacin de respuestas. Los resultados devueltos por el
Modelo al Controlador son depositados por ste en una variable de
peticin, sesin o aplicacin, segn el alcance que deban tener. A
continuacin, el Controlador invoca a la pgina J SP que debe
encargarse de generar la vista correspondiente, esta pgina
acceder a la variable de mbito donde estn depositados los
resultados y los utilizar para generar dinmicamente la respuesta
XHTML que ser enviada al cliente.
PRCTICA 1.1. ENVO Y VISUALIZACIN DE MENSAJES
Descripcin
Para comprender la importancia de esta arquitectura, vamos a desarrollar
una aplicacin Web siguiendo este patrn MVC. La aplicacin consistir en un
sencillo sistema de envo y visualizacin de mensajes a travs de la Web, cuyas
pginas se muestran en la figura 5. Cada mensaje estar formado por un
destinatario, un remitente y un texto.
La pgina de inicio muestra dos enlaces con las opciones del usuario, la de
visualizacin de mensajes le llevar a otra pgina (mostrar.htm) donde se le
solicitar el nombre del destinatario cuyos mensajes quiere visualizar. En caso de
tener mensajes asociados se le enviar a una pgina donde se le mostrar una tabla
con todos sus mensajes, indicando para cada uno de ellos el remitente y el
contenido del mensaje. Por otro lado, la opcin de envo de mensajes le llevar a
una pgina en la que se le solicitarn los datos del mensaje que quiere enviar,
devolvindolo despus a la pgina de inicio una vez que el mensaje ha sido
almacenado.
26 STRUTS RA-MA












Fig. 5. Pginas de la aplicacin
Desarrollo
Los mensajes manejados por la aplicacin sern almacenados en una tabla
cuya estructura se indica en la figura 6.





Fig. 6. Tabla para el almacenamiento de mensajes
cadena de texto texto
cadena de texto destinatario
cadena de texto remitente
Tipo Datos Nombre Campo
cadena de texto texto
cadena de texto destinatario
cadena de texto remitente
Tipo Datos Nombre Campo
RA-MA CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 27

El desarrollo de esta aplicacin se realizar siguiendo el patrn Modelo
Vista Controlador, donde tendremos un servlet llamado controlador en el que se
centralizarn todas las peticiones procedentes desde el cliente.
El Modelo estar implementado mediante una clase a la que llamaremos
Operaciones que dispondr de dos mtodos: grabarMensaje(), encargado de
almacenar en la base de datos los datos de un mensaje, y obtenerMensajes(), cuya
funcin ser la de recuperar la lista de mensajes asociados al destinatario que se
proporciona como parmetro.
Los mensajes sern manipulados mediante una clase J avaBean llamada
Mensaje, que encapsular los tres datos asociados a un determinado mensaje.
En cuanto a las vistas, sern implementadas mediante cinco pginas, dos
XHTML (inicio.htm y mostrar.htm) y tres J SP (envio.jsp, ver.jsp y
nomensajes.jsp). Utilizando el parmetro operacion insertado en la URL, las
pginas inicio.htm, mostrar.htm y envio.jsp indicarn al servlet controlador el tipo
de accin que se debe llevar a cabo en cada peticin.
Listados
A continuacin presentamos el cdigo de cada uno de los elementos de la
aplicacin.
Clase Mensaje
package j avabeans;
publ i c cl ass Mensaj e {
pr i vat e St r i ng r emi t e;
pr i vat e St r i ng dest i no;
pr i vat e St r i ng t ext o;
publ i c Mensaj e( ) {}
//constructor que permite crear un objeto
//Mensaje a partir de los datos del mismo
publ i c Mensaj e( St r i ng r emi t e, St r i ng dest i no,
St r i ng t ext o) {
t hi s. r emi t e=r emi t e;
t hi s. dest i no=dest i no;
t hi s. t ext o=t ext o;
}
publ i c voi d set Remi t e( St r i ng r emi t e) {
t hi s. r emi t e=r emi t e;
}
28 STRUTS RA-MA

publ i c St r i ng get Remi t e( ) {
r et ur n t hi s. r emi t e;
}
publ i c voi d set Dest i no( St r i ng dest i no) {
t hi s. dest i no=dest i no;
}
publ i c St r i ng get Dest i no( ) {
r et ur n t hi s. dest i no;
}
publ i c voi d set Text o( St r i ng t ext o) {
t hi s. t ext o=t ext o;
}
publ i c St r i ng get Text o( ) {
r et ur n t hi s. t ext o;
}
}
Clase Controlador
package ser vl et s;
i mpor t j avax. ser vl et . *;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t j ava. i o. *;
i mpor t j ava. ut i l . *;
i mpor t j avabeans. *;
i mpor t model o. *;
publ i c cl ass Cont r ol ador ext ends Ht t pSer vl et {
publ i c voi d ser vi ce( Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Ser vl et Except i on, I OExcept i on {
St r i ng op=r equest . get Par amet er ( " oper aci on" ) ;
//acceso a la pgina de envo de mensajes
i f ( op. equal s( " envi o" ) )
r esponse. sendRedi r ect ( " envi o. j sp" ) ;
/ / gr abaci n de un mensaj e
i f ( op. equal s( " gr abar " ) ) {
Mensaj e men=( Mensaj e) r equest . get At t r i but e( " mensa" ) ;
Oper aci ones oper =new Oper aci ones( ) ;
oper . gr abaMensaj e( men) ;
r esponse. sendRedi r ect ( " i ni ci o. ht m" ) ;
}

RA-MA CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 29

//acceso a la pgina de solicitud de mensajes
i f ( op. equal s( " muest r a" ) )
r esponse. sendRedi r ect ( " most r ar . ht m" ) ;
/ / acceso a l a l i st a de mensaj es del usuar i o
i f ( op. equal s( " ver " ) ) {
Oper aci ones oper =new Oper aci ones( ) ;
Ar r ayLi st mensaj es=oper . obt ener Mensaj es(
r equest . get Par amet er ( " nombr e" ) ) ;
r equest . set At t r i but e( " mensaj es" , mensaj es) ;
Request Di spat cher r d=r equest .
get Request Di spat cher ( " / ver . j sp" ) ;
r d. f or war d( r equest , r esponse) ;
}
}
}
Clase Operaciones
package model o;
i mpor t j ava. sql . *;
i mpor t j avabeans. *;
i mpor t j ava. ut i l . *;
publ i c cl ass Oper aci ones {
/ / mt odo comn par a l a obt enci n
/ / de conexi ones
publ i c Connect i on get Connect i on( ) {
Connect i on cn=nul l ;
t r y{
Cl ass. f or Name( " sun. j dbc. odbc. J dbcOdbcDr i ver " ) ;
cn=Dr i ver Manager . get Connect i on( " j dbc: odbc: mensaj es" ) ;
}
cat ch( Except i on e) {e. pr i nt St ackTr ace( ) ; }
r et ur n cn;
}
publ i c Ar r ayLi st obt ener Mensaj es( St r i ng dest i no) {
Connect i on cn=nul l ;
Ar r ayLi st mensaj es=nul l ;
St at ement st ;
Resul t Set r s;
t r y{
cn=get Connect i on( ) ;
st =cn. cr eat eSt at ement ( ) ;
30 STRUTS RA-MA

St r i ng t sql ;
t sql =" sel ect * f r ommensaj es wher e dest i nat ar i o=' " +
dest i no+" ' " ;
r s=st . execut eQuer y( t sql ) ;
mensaj es=new Ar r ayLi st ( ) ;
//para cada mensaje encontrado crea un objeto
//Mensaje y lo aade a la coleccin ArrayList
whi l e( r s. next ( ) ) {
Mensaj e m=new Mensaj e( r s. get St r i ng( " r emi t ent e" ) ,
r s. get St r i ng( " dest i nat ar i o" ) ,
r s. get St r i ng( " t ext o" ) ) ;
mensaj es. add( m) ;
}
cn. cl ose( ) ;
}
cat ch( Except i on e) {e. pr i nt St ackTr ace( ) ; }
r et ur n( mensaj es) ;
}
publ i c voi d gr abaMensaj e( Mensaj e m) {
Connect i on cn;
St at ement st ;
Resul t Set r s;
t r y{
cn=get Connect i on( ) ;
st =cn. cr eat eSt at ement ( ) ;
St r i ng t sql ;
/ / a par t i r de l os dat os del mensaj e const r uye
/ / l a cadena SQL par a r eal i zar su i nser i n
t sql =" I nser t i nt o mensaj es val ues( ' " ;
t sql +=m. get Dest i no( ) +" ' , ' " +
m. get Remi t e( ) +" ' , ' " +
m. get Text o( ) +" ' ) " ;
st . execut e( t sql ) ;
cn. cl ose( ) ;
}
cat ch( Except i on e) {e. pr i nt St ackTr ace( ) ; }
}
}
inicio.htm
<ht ml >
RA-MA CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 31

<body>
<cent er >
<br / ><br / >
<a hr ef =" cont r ol ador ?oper aci on=envi o" >
Envi ar mensaj e
</ a><br / ><br / >
<a hr ef =" cont r ol ador ?oper aci on=muest r a" >
Leer mensaj es
</ a>
</ cent er >
</ body>
</ ht ml >
mostrar.htm
<ht ml >
<body>
<cent er >
<br / ><br / >
<f or mact i on=" cont r ol ador ?oper aci on=ver " met hod=" post " >
I nt r oduzca su nombr e:
<i nput t ype=" t ext " name=" nombr e" ><br ><br >
<i nput t ype=" submi t " >
</ f or m>
</ cent er >
</ body>
</ ht ml >
envio.jsp
<ht ml >
<head>
<t i t l e>envi o</ t i t l e>
</ head>
<!--captura de datos e insercin en el Javabean-->
<j sp: useBean i d=" mensa" scope=" r equest "
cl ass=" j avabeans. Mensaj e" / >
<j sp: set Pr oper t y name=" mensa" pr oper t y=" *" / >
<%i f ( r equest . get Par amet er ( " t ext o" ) ! =nul l ) {%>
<j sp: f or war d page=" cont r ol ador ?oper aci on=gr abar " / >
<%}%>

32 STRUTS RA-MA

<body>
<cent er >
<h1>Gener aci n de mensaj es</ h1>
<f or mmet hod=" post " >
<br / ><br / >
<b>Dat os del mensaj e: </ b><br / ><br / >
I nt r oduzca dest i nat ar i o: <i nput t ype=" t ext "
name=" dest i no" ><br / >
<br / >
I nt r oduzca r emi t ent e : <i nput t ype=" t ext "
name=" r emi t e" ><br / >
<br / >
I nt r oduzca t ext o : <br / >
<t ext ar ea name=" t ext o" >
</ t ext ar ea>
<hr / ><br / >
<i nput t ype=" submi t " name=" Submi t " val ue=" Envi ar " >
<i nput t ype=" r eset " val ue=" Reset " >
</ f or m>
</ cent er >
</ body>
</ ht ml >
ver.jsp
<%@page i mpor t =" j avabeans. *, j ava. ut i l . *" %>
<ht ml >
<head>
<t i t l e>ver </ t i t l e>
</ head>
<body>
<cent er >
<%St r i ng nombr e=r equest . get Par amet er ( " nombr e" ) ; %>
<h1>
Mensaj es par a <%=nombr e%>
</ h1>
<t abl e bor der =1>
<t r ><t h>Remi t ent e</ t h><t h>Mensaj e</ t h></ t r >
<%bool ean men=f al se;
Ar r ayLi st mensaj es=
( Ar r ayLi st ) r equest . get At t r i but e( " mensaj es" ) ;
i f ( mensaj es! =nul l )
RA-MA CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 33

//si existen mensajes para ese destinatario
//se generar una tabla con los mismos
f or ( i nt i =0; i <mensaj es. si ze( ) ; i ++) {
Mensaj e m=( Mensaj e) mensaj es. get ( i ) ;
i f ( ( m. get Dest i no( ) ) . equal sI gnor eCase( nombr e) ) {
men=t r ue; %>
<t r ><t d><%=m. get Remi t e( ) %></ t d><t d>
<%=m. get Text o( ) %></ t d>
</ t r >
<%}
}
i f ( ! men) {%>
<! - - si no hay mensaj es se env a al usuar i o
a l a pgi na nomensaj es. j sp- - >
<j sp: f or war d page=" nomensaj es. j sp" / >
<%}%>
</ t abl e>
<br / ><br / >
<a hr ef =" i ni ci o. ht m" >I ni ci o</ a>
</ cent er >
</ body>
</ ht ml >
nomensajes.jsp
<ht ml >
<head>
<t i t l e>nomensaj es</ t i t l e>
</ head>
<body>
<cent er >
<h2>
Lo si ent o, <%=r equest . get Par amet er ( " nombr e" ) %>
no t i ene mensaj es
</ h2>
<br / ><br / ><br / ><br / >
<a hr ef =" i ni ci o. ht m" >I ni ci o</ a>
</ cent er >
</ body>
</ ht ml >



2Captulo 2
EL FRAMEWORK STRUTS
La arquitectura Modelo Vista Controlador constituye como hemos visto
una excelente solucin a la hora de implementar una aplicacin Web en J ava,
aunque desde luego no est exenta de inconvenientes.
Si observamos detenidamente el ejemplo de cdigo presentado en el
Captulo anterior, comprobaremos la existencia de dos puntos dbiles que para
grandes aplicaciones podran traducirse en un desarrollo excesivamente complejo y
difcilmente mantenible. Estos puntos dbiles son:
Extensin del Controlador. En aplicaciones en donde haya que
gestionar varios tipos de peticiones, esto se traducir en un elevado
nmero de lneas de cdigo en el servlet controlador, hacindolo
demasiado complejo y propenso a errores.
Cdigo Java en pginas JSP. La presencia de cdigo J ava en una
pgina J SP, aunque proporciona una gran flexibilidad a la hora de
generar las vistas, hace difcilmente mantenibles las pginas y
obstaculiza la labor del diseador de las mismas.
Como solucin a estos problemas se puede optar por dividir el servlet
controlador en varios servlets ms pequeos, encargndose cada uno de ellos de
gestionar un tipo de peticin, as como crear libreras de acciones J SP
personalizadas que encapsulen la mayor parte del cdigo J ava utilizado en la
generacin de las vistas.
36 STRUTS RA-MA

Otra opcin consiste en emplear algn tipo de utilidad que facilite las
tareas descritas anteriormente; y es aqu donde entra en juego Struts.
2.1 FUNDAMENTOS DE STRUTS
Struts es un framework o marco de trabajo desarrollado por el grupo
Apache, que proporciona un conjunto de utilidades cuyo objetivo es facilitar y
optimizar los desarrollos de aplicaciones Web con tecnologa J avaEE, siguiendo el
patrn MVC.
El empleo de Struts en los desarrollos ofrece numerosos beneficios al
programador, entre los que podramos destacar:
Control declarativo de peticiones. Con Struts el programador no
tiene que preocuparse por controlar desde cdigo las distintas
acciones a realizar en funcin del tipo de peticin que llega al
Controlador. Este proceso es implementado por defecto por uno de
los componentes que proporciona Struts, encargndose nicamente
el programador de definir en un archivo de configuracin XML los
mapeos entre tipos de peticin y acciones a ejecutar.
Utilizacin de direcciones virtuales. A fin de evitar la inclusin
directa dentro del cdigo de la aplicacin de las URL de los
recursos para hacer referencia a los mismos, Struts proporciona
unos tipos de objetos que permiten referirse a estos recursos
mediante direcciones virtuales asociadas a los mismos. La
asociacin entre una direccin virtual y su correspondiente URL o
direccin real se realiza en un archivo de configuracin, de este
modo cualquier cambio en la localizacin de un recurso no afectar
al cdigo de la aplicacin.
Manipulacin de datos con JavaBean. Como hemos podido
comprobar, los J avaBeans constituyen una pieza importante dentro
de la arquitectura MVC al facilitar el transporte de datos entre las
capas de la aplicacin. Struts proporciona un slido soporte para la
manipulacin de datos mediante J avaBeans, encargndose
automticamente el framework de la instanciacin de los mismos,
su rellenado con los datos procedentes del cliente y la recuperacin
y almacenamiento de los objetos en las variables de mbito; todo
esto sin necesidad de que el programador tenga que escribir una
sola lnea de cdigo.
RA-MA CAPTULO 2. EL FRAMEWORK STRUTS 37

Juego de libreras de acciones JSP. A fin de poder reducir al
mnimo la cantidad de instrucciones de cdigo J ava dentro de una
pgina J SP, Struts proporciona un amplio conjunto de libreras de
acciones predefinidas con las que se pueden realizar la mayor parte
de las operaciones que tienen lugar dentro de una pgina J SP, tales
como el acceso a las variables de mbito y parmetros de peticin,
la iteracin de colecciones, manipulacin de J avaBeans, etc.
La aportacin de Struts al desarrollo de aplicaciones MVC se dirige
bsicamente a la construccin del Controlador y la Vista de una aplicacin,
dejando total libertad al programador en la implementacin del Modelo y pueda as
elegir la tecnologa que crea ms conveniente en cada caso.
Esto no significa que los beneficios en la utilizacin de Struts no se vean
reflejados tambin en esta capa, ya que la manera en la que Struts permite
implementar el Controlador ofrece un fuerte desacoplamiento entre ste y el
Modelo, al tiempo que facilita una buena cohesin entre ambos.
2.2 COMPONENTES DE STRUTS
El marco de trabajo Struts est constituido por los siguientes elementos o
componentes:
Archivos de configuracin.
El API de Struts.
Libreras de acciones J SP.
2.2.1 Archivos de configuracin
Adems del descriptor de despliegue web.xml definido por la
especificacin J avaEE, una aplicacin Struts requiere de otros archivos de
configuracin adicionales. El ms importante de ellos es struts-config.xml, entre
otros elementos, en l se registran y configuran los distintos objetos Struts que van
a ser utilizados por la aplicacin, por lo que cada una deber tener su propio
archivo struts-config.xml.
La figura 7 ilustra la estructura tipo de este documento. Segn vayamos
avanzando en el estudio de los objetos Struts y la manera de utilizarlos en las
aplicaciones, iremos conociendo los distintos elementos o tags que se utilizan en la
construccin de un documento struts-config.xml.
38 STRUTS RA-MA












Fig. 7. Estructura bsica de un documento struts-config.xml
Adems de struts-config.xml una aplicacin Struts puede incorporar otros
archivos de configuracin, entre los ms importantes destacamos:
ApplicationResource.properties. Se trata de un archivo de texto
plano para el almacenamiento de cadenas de texto en forma de
parejas nombre=valor, siendo valor el texto y nombre una clave o
identificador asociado. Cada vez que se requiera hacer uso de
alguna de estas cadenas desde la aplicacin, se har utilizando la
clave asociada a la misma. De esta manera, si el texto tiene que ser
modificado, el cambio se realizar en el archivo de texto, no en el
cdigo.
Entre las utilidades de este archivo est la internacionalizacin de
aplicaciones, pudindose definir tantos archivos de este tipo como
idiomas se quiera mostrar en la aplicacin, o el almacenamiento de
mensajes de error personalizados. En Captulos posteriores se
estudiar con detalle la utilizacin de este archivo.
RA-MA CAPTULO 2. EL FRAMEWORK STRUTS 39

Este archivo deber estar incluido dentro de alguno de los paquetes
de la aplicacin, adems, se deber incluir la siguiente entrada en
el archivo de configuracin struts-config.xml para que Struts pueda
localizarlo:
<message-resources
parameter="paquete/ApplicationResource"/>
validator-rules.xml. Contiene las reglas de los validadores
utilizados para la validacin automtica de los datos de usuario.
validation.xml. Archivo utilizado para la asignacin de
validadores a los campos de los formularios. En el Captulo
dedicado a la validacin de datos de usuario analizaremos con
detalle el significado y uso tanto de este archivo como del anterior.
tiles-defs.xml. Como tendremos oportunidad de ver, los tiles o
plantillas representan una de las caractersticas ms interesantes de
Struts de cara a optimizar la creacin de vistas. A fin de reutilizar
los distintos modelos de plantillas dentro de una aplicacin, stos
debern ser definidos dentro de este archivo.
2.2.2 El API de Struts
El API de Struts lo forman el conjunto de clases de apoyo que el
framework proporciona para estructurar las aplicaciones y simplificar su desarrollo.
La mayor parte de estas clases se utilizan en la creacin del Controlador y de
J avaBeans para el tratamiento de datos, siendo los paquetes ms importante de
todos org.apache.struts.action y org.apache.struts.actions.
De cara a ir familiarizndonos con ellas, vamos a describir a continuacin
las caractersticas de las principales clases que forman este API:
ActionServlet. Un objeto ActionServlet constituye el punto de
entrada de la aplicacin, recibiendo todas las peticiones HTTP que
llegan de la capa cliente. Se trata bsicamente de un servlet HTTP
cuya clase hereda a HttpServlet.
El objeto ActionServlet lleva a cabo la siguiente funcionalidad
dentro de una aplicacin: cada vez que recibe una peticin desde el
cliente y a fin de determinar la operacin a realizar, extrae la
40 STRUTS RA-MA

ltima parte de la URL y la contrasta con la informacin contenida
en el archivo de configuracin struts-config.xml, a partir de la cual,
el objeto lleva a cabo la instanciacin del J avaBean (ActionForm)
asociado a la accin, lo rellena con los datos procedentes del
formulario cliente y deposita la instancia en el contexto
correspondiente, pasando a continuacin el control de la peticin al
objeto Action encargado de procesarla.
Es por ello que en la mayora de las aplicaciones los
programadores no necesitan extender la funcionalidad de
ActionServlet y utilizan directamente esta clase, debiendo
nicamente realizar su registro en web.xml.
Action. Como acabamos de comentar, los objetos Action son los
responsables de procesar los distintos tipos de peticiones que
llegan a la aplicacin. El principal mtodo con que cuenta esta
clase es execute(), mtodo que ser invocado por ActionServlet al
transferir la peticin al objeto. As pues, por cada tipo de peticin
que se vaya a controlar, el programador deber definir una
subclase de Action y sobrescribir el mtodo execute(),
incluyendo en l las instrucciones requeridas para el tratamiento de
la peticin, tales como llamadas a los mtodos de la lgica de
negocio implementada en el modelo o la transferencia de
resultados a las vistas para su presentacin.
ActionForm. Los objetos ActionForm son un tipo especial de
J avaBean que facilitan el transporte de datos entre las capas de la
aplicacin. Son utilizados por ActionServlet para capturar los datos
procedentes de un formulario XHTML y envirselos al objeto
Action correspondiente, todo ello sin recurrir a los incmodos
request.getParameter(). Para ello, el programador deber extender
esta clase y proporcionar los datos miembro necesarios para el
almacenamiento de los datos, as como los correspondientes
mtodos set/get que den acceso a los mismos.
ActionMapping. Un objeto de tipo ActionMapping representa una
asociacin entre una peticin y el objeto Action que la tiene que
procesar. Contiene informacin sobre el path o tipo de URL que
provoca la ejecucin de la accin, as como de las posibles vistas
que se pueden presentar al cliente tras su procesamiento.
RA-MA CAPTULO 2. EL FRAMEWORK STRUTS 41

Cuando el Controlador ActionServlet invoca al mtodo execute()
de un objeto Action para el procesamiento de una peticin,
proporciona como parmetro un objeto ActionMapping con la
informacin asociada a la misma, pudindose hacer uso de sus
mtodos para encaminar al usuario a cualquiera de las vistas
asociadas al objeto una vez que la peticin ha sido procesada.
ActionForward. Como ya mencionamos al hablar de las ventajas
de Struts, las aplicaciones que utilizan este framework trabajan con
direcciones virtuales en vez de reales. Las direcciones virtuales,
ms conocidas en Struts como forwards, son manejadas desde
cdigo a travs de objetos ActionForward.
La clase ActionForward encapsula los detalles sobre la
localizacin de un recurso, de modo que cada vez que se quiera
transferir una peticin desde cdigo o redireccionar al usuario a
una determinada pgina se har utilizando objetos ActionForward.
Por ejemplo, tal y como tendremos oportunidad de ver ms
adelante, la manera de indicar desde el mtodo execute() de un
objeto Action a ActionServlet que debe generar una determinada
vista ser devolvindole el objeto ActionForward asociada a la
misma.
Todos estos objetos Struts utilizados por la aplicacin, y otros que
estudiaremos en prximos Captulos, debern estar apropiadamente definidos en el
archivo de configuracin struts-config.xml.
2.2.3 Libreras de acciones JSP
Las libreras de tags o acciones J SP constituyen otro de los componentes
esenciales de Struts. El amplio conjunto de acciones existentes permite realizar la
gran mayora de las tareas propias de una pgina J SP sin necesidad de incluir en la
misma ni una sola lnea de cdigo J ava, facilitando as la comprensin y posterior
mantenimiento de las vistas.
Struts proporciona las siguientes libreras:
HTML. Incluye acciones para la construccin de formularios
HTML, incorporando parte de la funcionalidad encargada de la
creacin de beans de tipo ActionForm y el rellenado de los mismos
con los valores de los controles. Adems de este tipo de acciones,
la librera html proporciona otros tags que facilitan la realizacin
42 STRUTS RA-MA

de tareas habituales en una pgina Web, como el enlace a otros
recursos de la aplicacin o la visualizacin de mensajes de error.
Bean. Esta librera incluye acciones para el acceso a propiedades
de un bean y parmetros de la peticin desde una pgina J SP.
Tambin incluye acciones para la definicin de nuevos beans y su
almacenamiento en el contexto de la aplicacin.
Logic. Los tags incluidos en esta librera realizan las operaciones
que normalmente se llevan a cabo utilizando las estructuras lgicas
de un lenguaje de programacin, como el recorrido de una
coleccin o la evaluacin de condiciones.
Nested. Extiende parte de los tags de las libreras anteriores a fin
de que puedan ser utilizados de forma anidada.
Tiles. Esta librera incluye acciones para la definicin de plantillas
y su reutilizacin en diferentes pginas.
2.3 FUNCIONAMIENTO DE UNA APLICACIN STRUTS
En la figura 8 podemos ver el esquema general de una aplicacin Web
Struts con cada uno de los componentes que la integran y la interaccin entre ellos.









Fig. 8. Estructura de una aplicacin Struts
ActionServlet
Vista
Modelo
Browser
Struts-config.xml
Action1
Action2
Action3
:
:
Struts
ActionForm1
ActionForm2
:
RA-MA CAPTULO 2. EL FRAMEWORK STRUTS 43

Cada vez que desde el navegador cliente llega una peticin al contenedor,
asociada con una aplicacin Struts, tendr lugar el proceso que describimos a
continuacin:
Anlisis de la URL de la aplicacin. El contenedor Web pasa la
peticin al objeto ActionServlet, ste, como ya hemos indicado,
utiliza la ltima parte de la URL de la peticin para determinar la
accin a realizar.
Como veremos en el primer ejemplo de cdigo que se presentar
en el Captulo siguiente, es habitual asignar como url-pattern del
objeto ActionServlet el valor *.do, esto significa que cualquier
URL procedente del cliente que termine en .do provocar que la
peticin sea capturada por este servlet.
Por ejemplo, suponiendo que el context path de una aplicacin
fuera /ejemplo y estuviera desplegada en el servidor
www.pruebas.com, las siguientes URL provocaran la ejecucin de
ActionServlet:
www.pruebas.com/ejemplo/listado.do
www.pruebas.com/ejemplo/registro.do
www.pruebas.com/ejemplo/busqueda.do
En este primer paso, ActionServlet extrae la parte de la URL que
se encuentra entre el context path de la aplicacin y la extensin
.do, obteniendo en cada caso los valores /listado, /registro y
/busqueda.
Determinacin de la accin a realizar. Utilizando el dato
obtenido en el paso anterior, el objeto ActionServlet realiza una
consulta en el archivo struts-config.xml para determinar las
operaciones a realizar. Para cada tipo de accin el archivo de
configuracin define la subclase Action que debe ser instanciada,
as como el objeto ActionForm asociado a la operacin. Tras
realizar la consulta en el archivo, ActionServlet lleva a cabo las
siguientes acciones:
- Crea u obtiene la instancia del objeto ActionForm y lo
rellena con los datos del formulario cliente.
44 STRUTS RA-MA

- Crea una instancia del objeto Action correspondiente e
invoca a su mtodo execute(), pasndole como parmetro
una referencia al objeto ActionForm.
Procesamiento de la peticin. En el mtodo execute() de la
subclase Action correspondiente se codificarn las acciones para el
procesamiento de la peticin. Se debe procurar aislar toda la lgica
de negocio en el Modelo, de manera que dentro de execute()
nicamente se incluyan las instrucciones para interaccionar con los
mtodos de ste, adems de aquellas otras encargadas del
almacenamiento de resultados en variables de contexto para su
utilizacin en las vistas.
Generacin de la vista. Como resultado de su ejecucin, el
mtodo execute() devuelve a ActionServlet un objeto
ActionForward que identifica al recurso utilizado para la
generacin de la respuesta. A partir de este objeto, ActionServlet
extrae la direccin virtual encapsulada en el mismo y utiliza este
valor para obtener del archivo struts-config.xml la direccin real de
la pgina XHTML o J SP correspondiente.




3Captulo 3
DESARROLLO DE UNA APLICACIN
CON STRUTS
A lo largo del Captulo anterior hemos estado analizando las caractersticas
y componentes del framework Struts, as como las ventajas que su utilizacin
ofrece para los programadores de aplicaciones Web.
Es el momento de verlo en accin, de aprender a utilizar y encajar cada una
de sus piezas. Para ello, vamos a comenzar con el desarrollo de una sencilla
aplicacin que construiremos con los distintos componentes que nos proporciona
Struts y que fueron estudiados en el Captulo anterior. Tras un primer anlisis sobre
el funcionamiento y estructura de la aplicacin, iremos detallando los diferentes
pasos a seguir para su creacin, aprovechando cada uno de ellos para presentar las
caractersticas a nivel de cdigo de los componentes que se van a utilizar y conocer
los detalles de su configuracin.
3.1 DESCARGA E INSTALACIN DEL FRAMEWORK
STRUTS
En el sitio Web http://struts.apache.org encontramos el paquete de
instalacin de Struts con todas las libreras y utilidades para poder trabajar con este
framework.
Dicho paquete se distribuye como un archivo .zip, pudiendo elegir entre
distintas versiones existentes en produccin de este framework. Dejando al margen
las versiones Struts 2.x, que sern tratadas en el ltimo Captulo del libro,
46 STRUTS RA-MA

descargaremos la ltima versin del tipo 1.x, que en el momento de escribir estas
lneas es la 1.3.9 (figura 9).








Fig. 9. Pgina de descarga del framework Struts
Una vez descargado y descomprimido el archivo, comprobamos que
incluye cuatro carpetas principales:
apps. Aplicaciones Struts de ejemplo.
docs. Documentacin y ayuda del API.
src. Cdigo fuente de Struts.
lib. Libreras con los componentes Struts.
Es esta ltima carpeta (lib) la que contiene los elementos principales para
poder crear aplicaciones Struts. Las principales libreras incluidas en esta carpeta
son:
struts-core-1.3.9.jar. Es la ms importante de todas, pues contiene
las principales clases que forman el API de struts.
struts-extras-1.3.9.jar. Incluye algunas clases extras para la
implementacin del Controlador.
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 47

struts-taglib-1.3.9.jar. Contiene todas las clases que implementan
las distintas acciones de las libreras de tags de struts.
struts-tiles-1.3.9.jar. Proporciona todos los componentes
necesarios para trabajar con plantillas.
commons-validator-1.3.1.jar. Incluye todo el soporte necesario
(clases y scripts de cliente) para la utilizacin de validadores en las
aplicaciones.
Si utilizamos algn IDE, como NetBeans o Eclipse, no ser necesario
realizar la descarga de estos archivos, pues los entornos de desarrollo ya los llevan
incorporados. No tendremos ms que indicar en el proyecto Web que queremos
usar el plug-in de Struts para que dichas libreras sean incorporadas al proyecto.
3.2 APLICACIN PRCTICA PARA VALIDACIN Y
REGISTRO DE USUARIOS
El programa de ejemplo que vamos a desarrollar en este apartado va a
consistir en una prctica y til aplicacin Web encargada de la validacin y registro
de usuarios en un sistema.









Fig. 10. Diagrama con las pginas de la aplicacin de validacin y registro
48 STRUTS RA-MA

Posteriormente, ampliaremos este ejemplo con el desarrollo de un
programa de consulta va Web de las llamadas realizadas por un determinado
usuario a travs de su operador de telefona. En esta primera versin tan slo
vamos a centrarnos, tal y como hemos indicado, en la funcionalidad para la
validacin de los usuarios contra la base de datos del operador, as como del
registro de stos en la misma.
La figura 10 muestra un esquema de la pginas que intervienen en la
aplicacin y la navegacin a travs de ellas.
3.2.1 Funcionamiento de la aplicacin
La pgina inicial de la aplicacin es login.jsp, y es la encargada de solicitar
los credenciales al usuario. En caso de que la combinacin de usuario y password
exista en la base de datos, se mostrar simplemente una pgina con un mensaje de
bienvenida personalizado para el cliente. Si la combinacin no es vlida, se
mostrar una pgina de error con un enlace a login.jsp para que vuelva a intentar
validarse. As mismo, la pgina inicial contendr un enlace a la pgina de registro
donde los usuarios no validados podrn darse de alta en el sistema.
Aunque la base de datos completa contiene un total de cuatro tablas, en la
figura 11 mostramos nicamente la tabla clientes de la base de datos telefonia,
que es la que vamos a utilizar en este ejemplo.




Fig. 11. Campos de la tabla clientes
3.2.2 Esquema de la aplicacin
Haciendo un primer anlisis del funcionamiento descrito, determinaremos
que, al margen del acceso inicial a la pgina login.jsp, existen cuatro tipos de
peticiones que se pueden lanzar desde el navegador cliente a la aplicacin:
Campo Tipo
nombre cadena de texto
apellidos cadena de texto
usuario cadena de texto
password cadena de texto
email cadena de texto
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 49

Peticin para validacin del usuario. Se produce desde la pgina
login.jsp al pulsar el botn validar, teniendo como objetivo la
validacin del usuario a partir de sus credenciales.
Peticin para registrar. Es la peticin que se produce desde la
pgina registro.jsp al pulsar el botn registrar y cuyo objetivo
ser llevar a cabo el alta del cliente a partir de los datos
introducidos.
Peticin para acceder a la pgina de login. Esta peticin es la que
se realiza desde el link aqu que aparece en la pgina error.jsp y
tiene como objetivo llevar de nuevo al usuario a la pgina de login.
Peticin para acceder a la pgina de registro. Esta peticin es la
que se realiza desde el link regstrese situado en la pgina
login.jsp y que tiene como objetivo llevar al usuario a la pgina de
registro.
Las dos primeras peticiones requieren un tratamiento especial por parte del
Controlador, mientras que las otras dos son simples enlaces a sendas vistas, sin
necesidad de ninguna accin previa por parte de la aplicacin.










Fig. 12. Esquema Struts de la aplicacin
ActionServlet
login.jsp
registro.jsp
bienvenida.jsp
error.jsp
ValidarAction
RegistrarAction
/
v
a
l
i
d
a
r
/
p
a
r
a
r
e
g
i
s
t
r
o
/
r
e
g
i
s
t
r
a
r
ValidacionForm
R
e
g
i
s
t
r
o
F
o
r
m
GestionClientes.class
validar()
registrar()
Vista Controlador Modelo
bienvenida, error
r
e
g
i
s
t
r
a
d
o
Struts-config.xml
/
l
o
g
i
n
50 STRUTS RA-MA

En la figura 12 se presenta un esquema general de cmo quedar la
estructura de la aplicacin, indicando los distintos componentes utilizados en la
construccin de la misma.
En ella podemos ver los cuatro tipos de peticiones comentadas
anteriormente que llegan a ActionServlet, indicando en la parte superior de la
flecha el path asociado a cada una de ellas.
En el interior del Controlador podemos apreciar las dos clases de accin
encargadas de gestionar las peticiones activas:
ValidarAction. Se encarga de gestionar la peticin /validar. Su
misin ser comprobar si el usuario est o no registrado en la base
de datos del sistema, para lo que se apoyar en el mtodo validar()
proporcionado por la clase GestionClientes del Modelo. El mtodo
execute() de ValidarAction recibir como parmetro un J avaBean
de la clase ValidacionForm con los credenciales suministrados por
el usuario y, como resultado de su ejecucin, devolver a
ActionServlet el objeto forward bienvenida o error, segn el
usuario est o no registrado.
RegistrarAction. Se encarga de gestionar la peticin /registrar
que enva los datos de usuario encapsulados en el J avaBean
RegistroForm para su ingreso en la base de datos, apoyndose para
ello en el mtodo registrar() del Modelo. Su mtodo execute()
devuelve el objeto forward registrado como indicacin de que el
registro se ha realizado correctamente. A efectos de simplificar la
aplicacin de ejemplo no se ha tenido en cuenta la situacin en la
que no haya sido posible registrar al usuario.
3.2.3 Construccin de la aplicacin
A continuacin, vamos a analizar en detalle el desarrollo de los distintos
componentes de la aplicacin, comenzando por la creacin de la estructura de
directorios de la misma.
3.2.3.1 ESTRUCTURA DE UNA APLICACIN WEB STRUTS
Una aplicacin Struts sigue la misma estructura de directorios de cualquier
aplicacin Web J avaEE, aunque antes de comenzar el desarrollo habr que incluir
en ella los distintos componentes del framework como son el archivo de
configuracin struts-config.xml, inicialmente vaco y que ser situado dentro del
directorio WEB-INF, y los archivos de librera (.jar) descargados con el paquete de
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 51

instalacin, los cuales se incluirn dentro del directorio \lib, aunque es posible que
no todos ellos sean utilizados en todas las aplicaciones.
Como ya hemos indicado, esta operacin se realizar de manera automtica
si utiliza algn IDE, como NetBeans o Eclipse, a travs del asistente para la
creacin de proyectos Web.
La estructura de directorios de la aplicacin deber quedar entonces tal y
como se indica en la figura 13. Si hemos utilizado algn IDE es posible que los
nombres de los archivos .jar sean algo diferentes a los indicados, si bien contendrn
los mismos elementos.










Fig. 13. Organizacin fsica de directorios de una aplicacin Web Struts
Como se aprecia en la figura anterior, en el directorio WEB-INF tan slo
hemos incluido, adems de web.xml, el archivo de configuracin struts-config.xml.
Cuando vayamos a construir aplicaciones que utilicen algunos de los componentes
especiales de Struts, como validadores o plantillas, veremos que ser necesario
incluir archivos de configuracin adicionales, tal y como se indic en el Captulo
anterior.
raiz raiz
WEB-INF WEB-INF
classes classes
(pginas J SP y XHTML)
web.xml
struts-config.xml
lib lib
(javabeans, objetos Action
y clases del Modelo)
antlr-2.7.2.jar, bsf-2.3.0.jar,
commons-beanutils-1.7.0.jar,
commons-chain-1.1.jar, commons-digester-1.8.jar,
commons-fileupload-1.1.1.jar, commons-io-1.1.jar,
commons-logging-1.0.4.jar, jstl-1.0.2.jar
commons-validator-1.3.1.jar, oro-2.0.8.jar,
standard-1.0.2.jar, struts-core-1.3.9.jar,
struts-el-1.3.9.jar, struts-extras-1.3.9.jar,
struts-faces-1.3.9.jar, struts-mailreader-dao-1.3.9.jar,
struts-scripting-1.3.9.jar, struts-taglib-1.3.9.jar y
struts-tiles-1.3.9.jar
52 STRUTS RA-MA

3.2.3.2 REGISTRO DEL SERVLET ACTIONSERVLET
Como ya se ha indicado, la mayora de las veces utilizaremos directamente
la propia clase ActionServlet para la creacin del servlet principal de la aplicacin.
Esta clase est incluida en el archivo struts-core-1.3.9.jar que hemos situado en el
directorio \lib de la aplicacin y habr que registrarla en el archivo de
configuracin web.xml, tal y como se indica en la figura 14.









Fig. 14. Registro del servlet controlador ActionServlet
Los principales elementos relacionados con el registro de ActionServlet
son:
servlet-class. Contiene el nombre cualificado de la clase.
init-param. ActionServlet utiliza dos parmetros de inicializacin:
por un lado el parmetro config que contiene la direccin relativa a
la aplicacin Web del archivo de configuracin de Struts, y por
otro debug, cuyo valor se establecer a 2.
url-pattern. Contiene el path de la URL de la peticin que da
acceso al servlet, en este caso cualquier valor que termine con la
extensin .do. Como ya se indic anteriormente, este formato suele
ser el utilizado habitualmente en Struts, pudindose utilizar
cualquier otro valor distinto a do. En vez del formato de extensin,
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 53

otro valor tpico que tambin suele utilizarse como url-pattern en
algunos casos es /do/*, que significa que cualquier peticin con
URL cuyo valor de servlet path sea /do har que se ejecute el
ActionServlet, utilizando el valor del path info para determinar la
accin a realizar.
3.2.3.3 CAPTURA DE DATOS DE USUARIO: LAS CLASES
VALIDACIONFORM Y REGISTROFORM
Estas clases sern utilizadas por Struts para encapsular los datos
procedentes de los formularios de validacin y registro, respectivamente. Ambas
heredan su funcionalidad de la clase ActionForm del API de Struts, encargndose
el programador nicamente de proporcionar los datos miembros para el
almacenamiento de los valores y de la implementacin de los mtodos
setXxx/getXxx correspondientes.
El siguiente listado corresponde al cdigo de estas dos clases, ambas las
hemos situado en el paquete javabeans:
package j avabeans;
i mpor t j avax. ser vl et . ht t p. Ht t pSer vl et Request ;
i mpor t or g. apache. st r ut s. act i on. *;
publ i c cl ass Val i daci onFor mext ends Act i onFor m{
//datos miembro
pr i vat e St r i ng usuar i o;
pr i vat e St r i ng passwor d;
/ / mt odos de acceso
publ i c St r i ng get Usuar i o( ) {
r et ur n usuar i o;
}
publ i c voi d set Usuar i o( St r i ng nombr e) {
t hi s. usuar i o = nombr e;
}
publ i c St r i ng get Passwor d( ) {
r et ur n passwor d;
}
publ i c voi d set Passwor d( St r i ng passwor d) {
t hi s. passwor d = passwor d;
}
}
package j avabeans;
i mpor t j avax. ser vl et . ht t p. Ht t pSer vl et Request ;
54 STRUTS RA-MA

i mpor t or g. apache. st r ut s. act i on. *;
publ i c cl ass Regi st r oFor mext ends Act i onFor m{
//datos miembro
pr i vat e St r i ng nombr e;
pr i vat e St r i ng apel l i dos;
pr i vat e St r i ng usuar i o;
pr i vat e St r i ng passwor d;
pr i vat e St r i ng emai l ;
/ / mt odos de acceso
publ i c St r i ng get Nombr e( ) {
r et ur n nombr e;
}
publ i c voi d set Nombr e( St r i ng nombr e) {
t hi s. nombr e = nombr e;
}
publ i c St r i ng get Apel l i dos( ) {
r et ur n apel l i dos;
}
publ i c voi d set Apel l i dos( St r i ng apel l i dos) {
t hi s. apel l i dos = apel l i dos;
}
publ i c St r i ng get Usuar i o( ) {
r et ur n usuar i o;
}
publ i c voi d set Usuar i o( St r i ng usuar i o) {
t hi s. usuar i o = usuar i o;
}
publ i c St r i ng get Passwor d( ) {
r et ur n passwor d;
}
publ i c voi d set Passwor d( St r i ng passwor d) {
t hi s. passwor d = passwor d;
}
publ i c St r i ng get Emai l ( ) {
r et ur n emai l ;
}
publ i c voi d set Emai l ( St r i ng emai l ) {
t hi s. emai l = emai l ;
}
}
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 55

Aunque no se va a hacer uso de ellos en este primer ejemplo, la clase
ActionForm proporciona adems dos mtodos reset() y validate(), que pueden ser
sobrescritos para tareas de limpieza y validacin de datos. Analizaremos en
profundidad estos mtodos en prximos Captulos.
A fin de que Struts pueda crear y gestionar objetos ActionForm, las clases
correspondientes deben quedar registradas en el archivo struts-config.xml, para lo
cual debemos aadir el elemento <form-beans> al principio del documento,
inmediatamente despus del elemento raz, e incluir en l un subelemento <form-
bean>por cada una de las subclases ActionForm que vayamos a utilizar. En
nuestro ejemplo quedara de la siguiente forma:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE st r ut s- conf i g PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s
Conf i gur at i on 1. 2/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/ st r ut s-
conf i g_1_2. dt d" >

<st r ut s- conf i g>
<f or m- beans>
<f or m- bean name=" Regi st r oFor m"
t ype=" j avabeans. Regi st r oFor m" / >
<f or m- bean name=" Val i daci onFor m"
t ype=" j avabeans. Val i daci onFor m" / >
</ f or m- beans>
:
Cada elemento <form-bean>incluye los siguientes atributos:
name. Identificador que asignar Struts a la instancia creada.
type. Nombre cualificado de la clase.
Indicando esta informacin en el archivo de configuracin, el programador
no necesitar incluir en la pgina J SP ninguna accin de tipo useBean para crear u
obtener la instancia, ni tampoco acciones setProperty/getProperty para acceder a
sus propiedades; Struts se encargar de realizar todas estas tareas de forma
transparente para el programador.
56 STRUTS RA-MA

3.2.3.4 IMPLEMENTACIN DEL MODELO
Al no depender directamente de Struts, su implementacin puede llevarse a
cabo en cualquier momento. Si la hemos incluido en este punto es porque, como
veremos ahora en el listado, los mtodos de negocio implementados en la clase
reciben como parmetros objetos de las clases ActionForm presentadas
anteriormente. No obstante, si se quiere tener un total desacoplamiento entre el
Modelo y el Controlador, podemos optar por utilizar como parmetros datos de
tipos bsicos de J ava que representen a cada una de las propiedades del bean que
sern utilizadas por el mtodo del Modelo, en vez de pasar el objeto ActionForm
completo. Otra opcin sera utilizar como parmetro un segundo JavaBean plano
independiente del API Struts.
Tal y como qued reflejado en el esquema de la figura 12, la
implementacin del Modelo se lleva a cabo mediante una clase llamada
GestionClientes; esta clase tiene dos mtodos validar() y registrar() que se
encargan respectivamente de comprobar la existencia del usuario en la base de
datos y de registrar nuevos usuarios en la misma. Ambos mtodos actan sobre la
tabla clientes cuya estructura se muestra en la figura 15.






Fig. 15. Tabla de clientes
Adems de GestionClientes, se incluye otra clase en el Modelo llamada
Datos que proporciona mtodos para la obtencin y cierre de conexiones con la
base de datos. Los mtodos de esta clase sirven de soporte para el resto de mtodos
del Modelo.


Texto email
Texto password
Texto usuario
Texto apellidos
Texto nombre
Tipo Campo
Texto email
Texto password
Texto usuario
Texto apellidos
Texto nombre
Tipo Campo
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 57

En el siguiente listado se muestra el cdigo de ambas clases:
package model o;
i mpor t j ava. sql . *;
public class Datos {
pr i vat e St r i ng dr i ver ;
pr i vat e St r i ng cadenacon;
publ i c Dat os( ) {
}
publ i c Dat os( St r i ng dr i ver , St r i ng cadenacon) {
//almacena los datos para la conexin
//con la base de datos
t hi s. dr i ver =dr i ver ;
t hi s. cadenacon=cadenacon;
}
publ i c Connect i on get Conexi on( ) {
Connect i on cn=nul l ;
t r y{
Cl ass. f or Name( dr i ver ) . newI nst ance( ) ;
cn=Dr i ver Manager . get Connect i on( cadenacon) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
r et ur n cn;
}
publ i c voi d ci er r aConexi on( Connect i on cn) {
t r y{
i f ( cn! =nul l && ! cn. i sCl osed( ) ) {
cn. cl ose( ) ;
}
}
cat ch( SQLExcept i on e) {
e. pr i nt St ackTr ace( ) ;
}
}
}

package model o;
i mpor t j ava. sql . *;
i mpor t j avabeans. *;
58 STRUTS RA-MA

public class GestionClientes {
Dat os dt ;
publ i c Gest i onCl i ent es( St r i ng dr i ver , St r i ng cadenacon) {
dt =new Dat os( dr i ver , cadenacon) ;
}
publ i c bool ean val i dar ( Val i daci onFor mvf ) {
bool ean est ado=f al se;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
//instruccin SQL para obtener los datos
//del usuario indicado
St r i ng quer y = " sel ect * f r omcl i ent es " ;
quer y+=" wher e passwor d =' " +vf . get Passwor d( ) ;
quer y+=" ' and usuar i o=' " +vf . get Usuar i o( ) +" ' " ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
est ado= r s. next ( ) ;
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n est ado;
}
}
publ i c voi d r egi st r ar ( Regi st r oFor mr f ) {
/ / gener a l a i nst r ucci n SQL de i nser ci n a par t i r
/ / de l os dat os al macenados en el J avaBean Usuar i o
St r i ng quer y = " I NSERT I NTO cl i ent es " ;
quer y+=val ues( ' " +r f . get Nombr e( ) +" ' , ' " +
r f . get Apel l i dos( ) +" ' , ' " +r f . get Usuar i o( ) +
" ' , ' " +r f . get Passwor d( ) +
" ' , ' " +r f . get Emai l ( ) +" ' ) " ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St at ement st =cn. cr eat eSt at ement ( ) ;
st . execut e( quer y) ;
st . cl ose( ) ;
dt . ci er r aConexi on( cn) ;
}
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 59

cat ch( Except i on e) {e. pr i nt St ackTr ace( ) ; }
}
}
3.2.3.5 PROCESAMIENTO DE PETICIONES: LAS CLASES
VALIDARACTION Y REGISTRARACTION
Tras el registro del servlet controlador ActionServlet, procedemos a la
definicin de las acciones, stas se implementarn mediante clases cuyos objetos se
van a encargar de procesar las peticiones que llegan al Controlador. Estas clases
debern heredar a Action y sobrescribir el mtodo execute() incluido en dicha
clase, incluyendo en l las instrucciones para el procesamiento de la peticin.
El formato del mtodo execute() se muestra en la figura 16.





Fig. 16. Mtodo execute() de la clase Action
Como podemos comprobar, el mtodo debe devolver al Controlador
ActionServlet un objeto ActionForward con los datos de la vista que deber ser
enviada al usuario.
As mismo, execute() recibe cuatro parmetros cuyo significado se describe
a continuacin:
mapping. Se trata de un objeto de la clase ActionMapping que
encapsula las opciones de configuracin definidas para la accin
en el archivo struts-config.xml, entre ellas las diferentes vistas a las
que podr ser encaminado el usuario una vez completada la accin.
Normalmente este objeto se emplea para obtener el objeto
ActionForward que ser devuelto al Controlador, para lo que
podrn utilizarse cualquiera de sus siguientes mtodos:
60 STRUTS RA-MA

- findForward(String forward). Devuelve el objeto
ActionForward asociado a la vista cuya direccin virtual se
especifica en el parmetro.
- getInputForward(). Devuelve un objeto ActionForward
asociado a la vista cuya direccin se especifica en el
atributo input del elemento <action>asociado a la accin.
form. Contiene el objeto de la subclase ActionForm creado por el
Controlador y que almacena los datos del formulario cliente. En
caso de que no se haya utilizado ningn ActionForm en la peticin,
este parmetro tendr el valor null.
request y response. Contienen respectivamente los objetos
HttpServletRequest y HttpServletResponse proporcionados por el
contenedor Web a ActionServlet. Utilizando estos objetos el
mtodo execute() podr tener acceso a las mismas opciones que se
encuentran disponibles para cualquier servlet HTTP.
A continuacin se muestra el cdigo de la clase ValidarAction, utilizada en
este programa de ejemplo para gestionar la accin de validacin de un usuario:
package ser vl et s;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t model o. *;
i mpor t j avabeans. *;
publ i c cl ass Val i dar Act i on ext ends Act i on {
publ i c Act i onFor war d execut e( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
//obtenemos los datos de conexin con la base
//de datos (driver y cadena de conexin) de
//los parmetros de contexto definidos
// en el archivo web.xml
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 61

new Gest i onCl i ent es( dr i ver , cadenaCon) ;
Val i daci onFor mvf =( Val i daci onFor m) f or m;
//invoca al mtodo validar() del Modelo para saber si
//el usuario est o no registrado
i f ( gc. val i dar ( vf ) ) {
r et ur n mappi ng. f i ndFor war d( " bi enveni da" ) ;
}
el se{
r et ur n mappi ng. f i ndFor war d( " er r or " ) ;
}
}
}
Como podemos ver en este listado, el mtodo execute() no incluye ninguna
instruccin que contenga lgica de negocio de la aplicacin. Para saber si el
usuario est o no registrado en la aplicacin hace uso del mtodo validar()
implementado en la clase GestionClientes. Si el usuario est registrado (el mtodo
validar() devolver el valor true), se devolver al Controlador el objeto
ActionForward asociado a la vista cuya direccin virtual es bienvenida, en caso
contrario el usuario ser encaminado a la vista error.
En cuanto a la clase RegistrarAction, he aqu el cdigo de la misma:
package ser vl et s;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t model o. *;
i mpor t j avabeans. *;
publ i c cl ass Regi st r ar Act i on ext ends Act i on {
publ i c Act i onFor war d execut e( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=
new Gest i onCl i ent es( dr i ver , cadenaCon) ;
Regi st r oFor mr f =( Regi st r oFor m) f or m;
gc. r egi st r ar ( r f ) ;
62 STRUTS RA-MA

r et ur n mappi ng. f i ndFor war d( " r egi st r ado" ) ;
}
}
Tanto en esta clase como en la anterior podemos observar cmo los datos
de conexin con la base de datos estn definidos fuera del cdigo de la aplicacin,
concretamente como parmetros de contexto accesibles para todos los
componentes de la aplicacin dentro del archivo web.xml:
<web- app ver si on=" 2. 5"
xml ns=ht t p: / / j ava. sun. com/ xml / ns/ j avaee
xml ns: xsi =ht t p: / / www. w3. or g/ 2001/ XMLSchema- i nst ance
xsi : schemaLocat i on=" ht t p: / / j ava. sun. com/ xml / ns/ j avaee
ht t p: / / j ava. sun. com/ xml / ns/ j avaee/ web- app_2_5. xsd" >
<cont ext - par am>
<par am- name>dr i ver </ par am- name>
<par am- val ue>sun. j dbc. odbc. J dbcOdbcDr i ver
</ par am- val ue>
</ cont ext - par am>
<cont ext - par am>
<par am- name>cadenaCon</ par am- name>
<par am- val ue>j dbc: odbc: t el ef oni a</ par am- val ue>
</ cont ext - par am>
<ser vl et >
:
Una vez implementadas las clases Action, es necesario registrarlas en el
archivo struts-config.xml dentro del elemento <action-mappings>, utilizando un
subelemento <action>para la definicin de los parmetros asociados a cada accin.
A travs de estos parmetros se le suministra a Struts toda la informacin que
necesita conocer sobre cada accin, como el path asociado a la misma o el objeto
ActionForm que deber ser utilizado en la llamada a execute(). A continuacin se
muestran las entradas a incluir en el archivo struts-config.xml para las acciones
utilizadas en esta aplicacin de ejemplo:
<st r ut s- conf i g>
:
<act i on- mappi ngs>
<act i on name=" Val i daci onFor m" pat h=" / val i dar "
scope=" r equest " t ype=" ser vl et s. Val i dar Act i on" >
<f or war d name=" bi enveni da" pat h=" / bi enveni da. j sp" / >
<f or war d name=" er r or " pat h=" / er r or . j sp" / >
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 63

</ act i on>
<act i on name=" Regi st r oFor m" pat h=" / r egi st r ar "
scope=" r equest " t ype=" ser vl et s. Regi st r ar Act i on" >
<f or war d name=" r egi st r ado" pat h=" / l ogi n. j sp" / >
</ act i on>
</ act i on- mappi ngs>
:
Seguidamente, describiremos el significado de los atributos indicados en el
elemento <action>:
path. Representa la direccin que debe ser utilizada en la URL de
la peticin para que ActionServlet derive la peticin a este objeto
Action, es decir, el valor que debe aparecer entre el context path de
la aplicacin y la extensin .do (servlet path). En el caso de la
pgina de entrada login.jsp, el atributo action del formulario
deber tomar el valor /validar.do, aunque si se utiliza el tag de
Struts <html:form>, basta con indicar /validar en dicho atributo.
name. Nombre del objeto ActionForm en el que ActionServlet
volcar los datos del formulario cliente desde el que se lanza la
peticin, y que ser pasado como parmetro en la llamada al
mtodo execute() de Action. El valor de este atributo debe
corresponder con alguno de los ActionForm definidos en el
apartado <form-beans>.
type. Nombre cualificado de la subclase Action.
validate. Indica si se deben validar o no los datos del ActionForm.
Si su valor es true, se invocar al mtodo validate() del bean antes
de hacer la llamada a execute(). El valor predeterminado es false.
scope. mbito de utilizacin del objeto ActionForm. Su valor
puede ser request, session o application, siendo request el valor
predeterminado.
input. Aunque no se utiliza en ninguno de los Action de este
ejemplo, indica la URL de la vista que debe ser enviada al cliente
en caso de que durante la validacin del bean (ejecucin del
mtodo validate()) se genere algn error. Ms adelante veremos un
ejemplo de utilizacin de este atributo.
64 STRUTS RA-MA

Como vemos adems en el listado anterior, cada elemento <action>puede
incluir uno o varios elementos <forward>. Estos elementos representan las posibles
vistas a las que se puede encaminar el usuario tras la ejecucin de la accin,
indicndose en cada uno de ellos la asociacin entre la direccin virtual de la vista
y la direccin fsica. Cada elemento <forward>dispone de dos atributos:
name. Nombre lgico o virtual asociado a la vista. Este valor es el
utilizado por el mtodo findForward() de ActionMapping para
crear el objeto ActionForward asociado a la vista a la que se tiene
que dirigir al usuario.
path. Contiene la URL relativa de la vista.
3.2.3.6 OBJETOS FORWARD GLOBALES
Adems de las peticiones /validar y /registrar que provocan la
ejecucin de los objetos Action anteriores, ActionServlet puede recibir tambin dos
peticiones por parte de cliente (/login y /pararegistro) que simplemente
deberan tener como consecuencia el reenvo de la peticin a una de las vistas de la
aplicacin, sin que sea necesario realizar ningn tratamiento especial por parte del
Controlador.
Para que esto sea posible se debern definir unos elementos <forward>
globales que relacionen las peticiones con las pginas a las que ser reenviado el
usuario. En estos elementos <forward>el atributo name contendr el path de la
peticin asociada y path la URL relativa de la pgina destino.
La definicin de los elementos <forward>globales se incluir dentro del
elemento <global-forward>, que a su vez estar situado entre <form-beans>y
<action-mappings>:
:
</ f or m- beans>
<gl obal - f or war ds>
<f or war d name=" l ogi n" pat h=" / l ogi n. j sp" / >
<f or war d name=" par ar egi st r o" pat h=" / r egi st r o. j sp" / >
</ gl obal - f or war ds>
<act i on- mappi ngs>
:
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 65

3.2.3.7 LAS PGINAS DE LA VISTA
La vista de esta aplicacin de ejemplo est constituida por cuatro pginas
J SP: login.jsp, registro.jsp, bienvenida.jsp y error.jsp. Todas ellas harn uso de
alguna de las libreras de acciones J SP proporcionadas por Struts. Estas libreras y
las clases que implementan las acciones se encuentran incluidas en el archivo de
librera struts-core-1.3.9.jar, pero para poder utilizar en una pgina J SP las acciones
definidas en una determinada librera habr que hacer uso de la directiva taglib e
indicar en su atributo uri el identificador asociado a dicha librera. Los
identificadores de las libreras de acciones de Struts estn definidos en los propios
archivos de librera .tld, siendo sus valores los indicados en la tabla de la figura 17.




Fig. 17. Identificadores de las libreras de Struts
Seguidamente vamos a analizar cada una de las cuatro pginas J SP
utilizadas en esta aplicacin.
login.jsp
Es la pgina de validacin de usuarios. Los datos son recogidos por un
formulario XHTML y enviados a ActionServlet que los encapsular en el objeto
ValidarForm. El siguiente listado corresponde con el cdigo de esta pgina:
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- ht ml "
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<body>
<cent er >
<h1>For mul ar i o de aut ent i caci n</ h1>
librera identificador
html http://struts.apache.org/tags-html
bean http://struts.apache.org/tags-bean
logic http://struts.apache.org/tags-logic
nested http://struts.apache.org/tags-nested
66 STRUTS RA-MA

<ht ml : f or mact i on=" / val i dar " met hod=" POST" >
<t abl e>
<t r >
<t d>Usuar i o: </ t d>
<t d><ht ml : t ext pr oper t y=" usuar i o" / ></ t d>
</ t r >
<t r >
<t d>Passwor d: </ t d>
<t d><ht ml : passwor d pr oper t y=" passwor d" / ></ t d>
</ t r >
<t r >
<t d col span=" 2" >
<br / >
<ht ml : submi t pr oper t y=" submi t " val ue=" Val i dar " / >
&nbsp; &nbsp;
<ht ml : r eset val ue =" Li mpi ar " / >
</ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
<br / >
<ht ml : l i nk f or war d=" par ar egi st r o" >Regi st r ese</ ht ml : l i nk>
</ cent er >
</ body>
</ ht ml : ht ml >
Como podemos ver, la pgina hace uso de la librera tags-html. sta
incluye acciones que se emplean para la construccin de interfaces grficas de
usuario basadas en formularios XHTML, adems de otros elementos dinmicos
tales como enlaces o imgenes. Aunque podran utilizarse etiquetas XHTML
estndares para la implementacin de los formularios dentro de una pgina J SP, el
empleo de estas acciones facilita enormemente la labor del desarrollador, puesto
que, adems de ser ms intuitivos sus nombres y atributos que los de las etiquetas
XHTML equivalentes, los tags html de Struts encapsulan parte de la funcionalidad
encargada de la manipulacin de los form beans y su rellenado con los datos
procedentes del formulario cliente.
Veamos a continuacin el funcionamiento y analicemos los atributos ms
importantes de las principales acciones incluidas en la librera tags-html:
<html:html>. Genera la correspondiente etiqueta <html>con las
caractersticas de localizacin propias del cliente.
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 67

<html:form>. Equivale a la etiqueta <form>y como en el caso de
sta sus principales atributos son method y action. El atributo
method contiene el mtodo de envo utilizado por la peticin,
siendo su valor por defecto POST. En cuanto a action, contiene
el path asociado al objeto Action que se encargar de tratar la
peticin, segn la informacin indicada en struts-config.xml.
Como se puede apreciar en el cdigo de las pginas anteriores, la
cadena indicada en action no incluye la extensin .do; una vez que
la accin sea interpretada en el servidor y transformada en su
equivalente etiqueta <form>, se establecer en el atributo action de
esta etiqueta la direccin relativa completa de la peticin,
aadiendo a la izquierda del valor original el context path de la
aplicacin y a su derecha la extensin .do asociada a
ActionServlet.
En el caso de login.jsp, y suponiendo que el directorio virtual de la
aplicacin Web es /ejemplo, la accin:
<html:form action="/validar" method="post">
ser transformada en:
<form action="/ejemplo/validar.do" method="post">
<html:text>. En vez de utilizar una nica etiqueta para todos,
Struts dispone de un tag diferente para la generacin de cada uno
de los controles grficos de la interfaz, haciendo ms intuitivo su
uso. En el caso de <html:text>, genera una caja de texto de una
nica lnea. Entre los atributos ms importantes de esta accin se
encuentran:
- property. Este atributo lo tienen todos los controles
grficos de la librera y representa el nombre de la
propiedad del objeto ActionForm en la que se volcar el
valor suministrado en el campo de texto. En caso de que la
propiedad del bean disponga de un valor inicial, este ser
utilizado para inicializar el contenido del control.
- maxlength. Nmero mximo de caracteres que admite el
control.
68 STRUTS RA-MA

- readonly. Indica si el contenido del control es de slo
lectura (true) o de lectura y escritura (false).
- onxxx. Representa cada uno de los manejadores de
eventos J avaScript que pueden ser capturados por el
control, siendo xxx el nombre del evento.
<html:password>. Genera una caja de texto de tipo password,
donde los caracteres introducidos se ocultan al usuario. Dispone de
los mismos atributos que <html:text>.
<html:textarea>. Genera un control de texto multilnea.
<html:submit>. Equivale al control XHTML <input
type=submit>. Al igual que ste, mediante su atributo value se
establece el texto mostrado por el botn.
<html:reset>. Limpia todos los campos del formulario, dejando
los valores por defecto establecidos. Equivale al contro XHTML
<input type=reset>.
<html:select>. Genera una lista de seleccin de opciones. Adems
de property, este elemento dispone del atributo size, mediante el
cual se indica si se generar una lista desplegable (size<=1) o una
lista abierta (size>1).
<html:option>. Se emplea para la generacin de las opciones en el
interior de una lista de seleccin. En su atributo value se especifica
el valor que ser asignado a la propiedad del bean especificada en
el atributo property de <html:select>, cuando la opcin sea
seleccionada.
<html:options>. Cuando las opciones de la lista se deben generar
dinmicamente a partir del contenido de una coleccin, resulta ms
cmodo utilizar este elemento en vez del anterior. En su atributo
name se indica el nombre del bean, existente en alguno de los
mbitos de la aplicacin, que contiene la coleccin de datos a
mostrar. Si la coleccin est contenida en alguna de las
propiedades del bean, se debera indicar en el atributo property el
nombre de dicha propiedad.
<html:optionsCollection>. Es similar al anterior, aunque este tag
se utiliza en aquellos casos en que la coleccin que contiene los
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 69

elementos de la lista es de objetos de tipo J avaBean. Adems de
name y property, habr que indicar en los atributos label y value
los nombres de las propiedades del bean que representan el texto y
valor de la opcin, respectivamente. El siguiente bloque de cdigo
de ejemplo genera una lista con los datos de los objetos de tipo
Libro contenidos en una coleccin llamada books, utilizando las
propiedades titulo e isbn del bean como texto y valor de cada
opcin:
<ht ml : sel ect >
<ht ml : opt i onsCol l ect i on name=" books"
l abel =" t i t ul o" val ue=" i sbn" / >
<ht ml : sel ect >
<html:checkbox>. Genera una casilla de verificacin. Uno de sus
principales atributos, value, indica el valor que se asignar a la
propiedad del bean especificada en property, siempre y cuando la
casilla se encuentre activada al hacer el submit del formulario.
<html:radio>. Genera un control de tipo radiobutton. Al igual que
ocurre con checkbox, el atributo value contiene el valor que ser
asignado a la propiedad del bean especificada en property. Todos
aquellos controles radiobutton con el mismo valor de atributo
property sern excluyentes entre s, siendo el contenido del
atributo value de aqul que est seleccionado el que se almacenar
en la propiedad del bean al realizar el submit del formulario.
Todos los tags anteriores corresponden a controles grficos de la interfaz
de usuario, por lo que debern aparecer siempre anidados dentro del elemento
<html:form>.
Adems de stos, hay otros tags importantes de esta librera que no estn
relacionados con el uso de formularios, como es el caso de <html:link> que
tambin se utiliza en la pgina login.jsp mostrada anteriormente. Este tag tiene
como finalidad la insercin de un enlace XHTML de tipo <a>, contando entre sus
principales atributos con:
forward. Nombre lgico del elemento <forward>global definido
en struts-config.xml, que hace referencia a la vista donde ser
enviado el usuario cuando se pulse el enlace. En la pgina login.jsp
existe un elemento <html:link>con el siguiente aspecto:
<html:link forward="pararegistro">Regstrese</html:link>
70 STRUTS RA-MA

que al ser solicitada la pgina ser transformado en:
<a href="/ejemplo/registro.jsp">Regstrese</a>
action. Su significado es el mismo que el del atributo action de
<html:form>, es decir, indica el path asociado al objeto Action que
se encargar de tratar la peticin. En caso de que deba ejecutarse
algn tipo de accin al activar este enlace, se utilizar este atributo
en vez de forward.
href. URL a la que ser enviado el usuario al pulsar el enlace.
linkName. Nombre de la marca local existente en la propia pgina
donde ser enviado el usuario al pulsar el enlace.
Segn se desprende de su significado, un elemento <html:link> debe
contener uno y slo uno de los atributos anteriores.
Otros elementos de esta librera como <html:errors>o <html:messages>
sern estudiados en el prximo Captulo.
registro.jsp
Se trata de la pgina de registro de nuevos usuarios. Los datos son
recogidos por un formulario XHTML y enviados a ActionServlet que los
encapsular en el objeto RegistroForm. El cdigo de esta pgina se muestra en el
siguiente listado:
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- ht ml "
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<body>
<cent er >
<h1>Regi st r o de usuar i os</ h1>
<ht ml : f or mact i on=" / r egi st r ar " met hod=" POST" >
<t abl e>
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 71

<t r >
<t d>Nombr e: </ t d>
<t d><ht ml : t ext pr oper t y=" nombr e" / ></ t d>
</ t r >
<t r >
<t d>Apel l i dos: </ t d>
<t d><ht ml : t ext pr oper t y=" apel l i dos" / ></ t d>
</ t r >
<t r >
<t d>Usuar i o: </ t d>
<t d><ht ml : t ext pr oper t y=" usuar i o" / ></ t d>
</ t r >
<t r >
<t d>Passwor d: </ t d>
<t d><ht ml : passwor d pr oper t y=" passwor d" / ></ t d>
</ t r >
<t r >
<t d>Emai l : </ t d>
<t d><ht ml : t ext pr oper t y=" emai l " / ></ t d>
</ t r >
<t r >
<t d col span=" 2" >
<br / >
<ht ml : submi t pr oper t y=" submi t " val ue=" Regi st r ar " / >
&nbsp; &nbsp;
<ht ml : r eset val ue =" Li mpi ar " / >
</ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
<br / >
</ cent er >
</ body>
</ ht ml : ht ml >
En esta pgina se hace uso de los tags de la librera html comentados
anteriormente.


72 STRUTS RA-MA

bienvenida.jsp
Es la pgina que se muestra al usuario una vez que se ha validado, he aqu
el cdigo de la misma:
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- bean"
pr ef i x=" bean" %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML
4. 01 Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >

<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type"
cont ent =" t ext / ht ml ; char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<h1>Bi enveni do a mi pgi na <i >
<bean: wr i t e name=" Val i daci onFor m"
pr oper t y=" usuar i o" / ></ i ></ h1>
</ body>
</ ht ml >
En esta pgina se hace uso tambin de una de las acciones de la librera
tags-bean, concretamente de <bean:write>. En el Captulo 5 se analizar el
funcionamiento de sta y del resto de las acciones que componen la librera, de
momento comentar que <bean:write>permite mostrar en la pgina los valores
almacenados en las propiedades de un bean.





RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 73

PRCTICA 3.1. LISTADO DE LLAMADAS DE USUARIOS
Con los conocimientos que ya tenemos sobre Struts estamos en
condiciones de implementar nuestra primera prctica con Struts. Para ello
partiremos del ejercicio de ejemplo que hemos ido desarrollando a lo largo del
Captulo.
Descripcin
Se trata de desarrollar una aplicacin que permita a los usuarios visualizar
el listado de las llamadas realizadas con cualquiera de los telfonos contratados con
un operador de telefona. Inicialmente el usuario acceder a una pgina de login
donde deber validarse y, en caso de que se trate de un usuario registrado, se le
mostrar una pgina donde deber elegir en una lista desplegable el telfono cuyo
listado de llamadas quiere visualizar, tras lo cual se le mostrar una nueva pgina
con los datos de las llamadas realizadas. La figura 18 muestra el aspecto de las
pginas de la aplicacin










Fig. 18. Pginas de la aplicacin
Desarrollo
Como ya se ha indicado, esta aplicacin ser desarrollada mediante Struts,
partiendo del desarrollo realizado en el ejemplo presentado anteriormente. En esta
74 STRUTS RA-MA

implementacin, adems de ValidarAction y RegistrarAction debemos crear una
nueva accin a la que llamaremos ListadoAction que se encargar de gestionar la
peticin que solicita el listado de llamadas a partir del telfono seleccionado. As
mismo, la accin ValidarAction deber ser modificada incluyendo las instrucciones
necesarias para que se recupere el listado de telfonos asociados al usuario antes de
devolver el objeto ActionForward asociado a la vista, la cual ya no ser
bienvenida.jsp sino opciones.jsp.
Por otro lado, ser necesario crear un nuevo ActionForm, al que
llamaremos OpcionesForm, que contendr el nmero de telfono seleccionado por
el usuario. Crearemos adems un J avaBean plano llamado LlamadaBean que
encapsule los datos de las llamadas telefnicas para facilitar su tratamiento desde la
aplicacin, el cual se apoyar a su vez en otro J avaBean llamado TarifaBean que
representa los datos de las tarifas. Tambin modificaremos ValidacionForm a fin
de que pueda almacenar la lista de telfonos asociada al usuario validado.
En cuanto al modelo, se crearn dos nuevas clases llamadas
GestionTelefonos y GestionLlamadas que proporcionarn toda la lgica necesaria
para obtener la informacin relativa a los nmeros de telfono del usuario y las
llamadas realizadas.
En la figura 19 tenemos un esquema completo de la base de datos
telefonia que utilizaremos en est aplicacin, indicndose las tablas que la
componen y los campos definidos en cada una de ellas.








Fig. 19. Base de datos de la aplicacin
Campo Tipo
nombre texto
apellidos texto
usuario texto
password texto
email texto
clientes
Campo Tipo
fkpassword texto
telefono numrico
telefonos
Campo Tipo
idtipotarifa numrico
nombretarifa texto
tarifas
Campo Tipo
idllamada numrico
fktelefono numrico
destino numrico
duracion numrico
fkidtipotarifa numrico
coste moneda
fecha fecha/hora
llamadas
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 75

Aunque no parezca muy ortodoxo, a fin de simplificar el modelo de datos
hemos utilizado el campo password del usuario como campo clave de la tabla
clientes. Este campo se utilizara, por tanto, como clave ajena en la tabla telefonos
para identificar los telfonos de cada cliente.
Listado
En primer lugar, mostraremos cmo quedar el archivo de configuracin
struts-config.xml de la aplicacin, en el que podemos ver los componentes que la
forman:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>

<! DOCTYPE st r ut s- conf i g PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s
Conf i gur at i on 1. 2/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/ st r ut s-
conf i g_1_2. dt d" >

<st r ut s- conf i g>
<f or m- beans>
<f or m- bean name=" Opci onesFor m"
t ype=" j avabeans. Opci onesFor m" / >
<f or m- bean name=" Regi st r oFor m"
t ype=" j avabeans. Regi st r oFor m" / >
<f or m- bean name=" Val i daci onFor m"
t ype=" j avabeans. Val i daci onFor m" / >
</ f or m- beans>
<gl obal - f or war ds>
<f or war d name=" l ogi n" pat h=" / l ogi n. j sp" / >
<f or war d name=" t or egi st r o" pat h=" / r egi st r o. j sp" / >
</ gl obal - f or war ds>
<act i on- mappi ngs>
<act i on name=" Val i daci onFor m" pat h=" / val i dar "
scope=" r equest " t ype=" ser vl et s. Val i dar Act i on" >
<f or war d name=" bi enveni da" pat h=" / opci ones. j sp" / >
<f or war d name=" er r or " pat h=" / l ogi n. j sp" / >
</ act i on>
<act i on i nput =" / r egi st r o. j sp" name=" Regi st r oFor m"
pat h=" / r egi st r ar " scope=" r equest "
t ype=" ser vl et s. Regi st r ar Act i on" >
<f or war d name=" r egi st r ado" pat h=" / l ogi n. j sp" / >
</ act i on>
76 STRUTS RA-MA

<act i on pat h=" / l i st ado" name=" Opci onesFor m"
t ype=" ser vl et s. Li st adoAct i on" par amet er =" oper aci on" >
<f or war d name=" l i st ado" pat h=" / l i st ado. j sp" / >
</ act i on>
</ act i on- mappi ngs>
</ st r ut s- conf i g>
Seguidamente mostramos el listado de los nuevos componentes de la
aplicacin y de aqullos que han sido modificados respecto al ejemplo analizado,
indicando en este ltimo caso los cambios realizados en fondo sombreado.
ValidacionForm.java
package j avabeans;

i mpor t or g. apache. st r ut s. act i on. *;
i mpor t j ava. ut i l . *;

publ i c cl ass Val i daci onFor mext ends Act i onFor m{
//almacena los credenciales del usuario
pr i vat e St r i ng usuar i o;
pr i vat e St r i ng passwor d;
/ / al macena el mensaj e asoci ado al r esul t ado
/ / de l a val i daci n
pr i vat e St r i ng mensaj e;
/ / al macena el conj unt o de t el f onos del usuar i o val i dado
pr i vat e Ar r ayLi st <I nt eger > t el ef onos;

publ i c St r i ng get Usuar i o( ) {
r et ur n usuar i o;
}
publ i c voi d set Usuar i o( St r i ng nombr e) {
t hi s. usuar i o = nombr e;
}
publ i c St r i ng get Passwor d( ) {
r et ur n passwor d;
}
publ i c voi d set Passwor d( St r i ng passwor d) {
t hi s. passwor d = passwor d;
}
publ i c voi d set Mensaj e( St r i ng mensaj e) {
t hi s. mensaj e=mensaj e;
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 77

}
publ i c St r i ng get Mensaj e( ) {
r et ur n mensaj e;
}
publ i c Ar r ayLi st <I nt eger > get Tel ef onos( ) {
r et ur n t el ef onos;
}
publ i c voi d set Tel ef onos( Ar r ayLi st <I nt eger > t el ef onos) {
t hi s. t el ef onos = t el ef onos;
}
}
OpcionesForm.java
package j avabeans;
i mpor t or g. apache. st r ut s. act i on. *;
publ i c cl ass Opci onesFor mext ends Act i onFor m{
//almacena el nmero de telfono
pr i vat e i nt numer o;
publ i c i nt get Numer o( ) {
r et ur n numer o;
}
publ i c voi d set Numer o( i nt i ) {
numer o = i ;
}
}
ValidarAction.java
package ser vl et s;

i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t model o. *;
i mpor t j avabeans. *;
publ i c cl ass Val i dar Act i on ext ends Act i on {
publ i c Act i onFor war d execut e( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
/ / obt i ene l os dat os del dr i ver y de l a cadena de
78 STRUTS RA-MA

//conexin de los parmetros de contexto
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=
new Gest i onCl i ent es( dr i ver , cadenaCon) ;
Val i daci onFor mvf =( Val i daci onFor m) f or m;
i f ( gc. val i dar ( vf ) ) {
Gest i onTel ef onos gt =
new Gest i onTel ef onos( dr i ver , cadenaCon) ;
/ / r ecuper a l os nmer os asoci ados al passwor d y
/ / l os al macena en el bean Val i daci onFor m
/ / par a que puedan ser accesi bl es
/ / a l a vi st a " bi enveni da"
vf . set Tel ef onos(
gt . get Tel ef onos( vf . get Passwor d( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " bi enveni da" ) ;
}
el se{
vf . set Mensaj e( " <h2>Combi naci n de usuar i o
y passwor d i ncor r ect a! </ h2>" ) ;
r et ur n mappi ng. f i ndFor war d( " er r or " ) ;
}
}
}
ListadoAction.java
package ser vl et s;

i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t or g. apache. st r ut s. act i ons. *;
i mpor t j avabeans. *;
i mpor t model o. *;
i mpor t j ava. ut i l . *;
publ i c cl ass Li st adoAct i on ext ends Act i on {
publ i c Act i onFor war d execut e( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 79

t hr ows Except i on {
Opci onesFor mof =( Opci onesFor m) f or m;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
//recupera el listado de llamadas asociadas al
//nmero y reenvia la peticin a la vista
r equest . set At t r i but e( " l l amadas" ,
gl . get TodasLl amadasTel ef ono( of . get Numer o( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " l i st ado" ) ;
}
/ / mt odo de apoyo a execut e
pr i vat e Gest i onLl amadas get Gest i onLl amadas
( Ht t pSer vl et Request r equest ) {
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
r et ur n new Gest i onLl amadas( dr i ver , cadenaCon) ;
}
}
LlamadaBean.java
package j avabeans;

i mpor t j ava. i o. *;
publ i c cl ass Ll amadaBean i mpl ement s Ser i al i zabl e{
pr i vat e i nt t el ef ono;
pr i vat e i nt dest i no;
pr i vat e i nt dur aci on;
pr i vat e St r i ng t ar i f a;
pr i vat e doubl e cost e;
pr i vat e St r i ng f echa;
publ i c Ll amadaBean( ) {
}
publ i c i nt get Tel ef ono( ) {
r et ur n t el ef ono;
}
publ i c voi d set Tel ef ono( i nt t el ef ono) {
t hi s. t el ef ono = t el ef ono;
}
publ i c i nt get Dest i no( ) {
r et ur n dest i no;
80 STRUTS RA-MA

}
publ i c voi d set Dest i no( i nt dest i no) {
t hi s. dest i no = dest i no;
}
publ i c i nt get Dur aci on( ) {
r et ur n dur aci on;
}
publ i c voi d set Dur aci on( i nt dur aci on) {
t hi s. dur aci on = dur aci on;
}
publ i c St r i ng get Tar i f a( ) {
r et ur n t ar i f a;
}
publ i c voi d set Tar i f a( St r i ng t ar i f a) {
t hi s. t ar i f a = t ar i f a;
}
publ i c doubl e get Cost e( ) {
r et ur n cost e;
}
publ i c voi d set Cost e( doubl e cost e) {
t hi s. cost e = cost e;
}
publ i c St r i ng get Fecha( ) {
r et ur n f echa;
}
publ i c voi d set Fecha( St r i ng f echa) {
t hi s. f echa = f echa;
}
}
TarifaBean.java
package j avabeans;

publ i c cl ass Tar i f aBean {
pr i vat e i nt i dt i pot ar i f a;
pr i vat e St r i ng nombr et ar i f a;
publ i c i nt get I dt i pot ar i f a( ) {
r et ur n i dt i pot ar i f a;
}
publ i c voi d set I dt i pot ar i f a( i nt i dt i pot ar i f a) {
t hi s. i dt i pot ar i f a = i dt i pot ar i f a;
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 81

}
publ i c St r i ng get Nombr et ar i f a( ) {
r et ur n nombr et ar i f a;
}
publ i c voi d set Nombr et ar i f a( St r i ng nombr et ar i f a) {
t hi s. nombr et ar i f a = nombr et ar i f a;
}
}
GestionLlamadas.java
package model o;

i mpor t j ava. sql . *;
i mpor t j ava. ut i l . *;
i mpor t j avabeans. *;
i mpor t j ava. t ext . *;
publ i c cl ass Gest i onLl amadas {
Dat os dt ;
publ i c Gest i onLl amadas( St r i ng dr i ver , St r i ng cadenacon) {
dt =new Dat os( dr i ver , cadenacon) ;
}
//obtiene todas las llamadas asociadas a
//un determinado telfono
publ i c Ar r ayLi st <Ll amadaBean> get TodasLl amadasTel ef ono(
i nt t el ef ono) {
St r i ng quer y = " sel ect * f r oml l amadas wher e " ;
quer y+=" f kt el ef ono=" +t el ef ono;
r et ur n get Ll amadas( quer y, t el ef ono) ;
}
pr i vat e Ar r ayLi st <Ll amadaBean> get Ll amadas(
St r i ng sql , i nt t el ef ono) {
Ar r ayLi st <Ll amadaBean> l l amadas=
new Ar r ayLi st <Ll amadaBean>( ) ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( sql ) ;
whi l e( r s. next ( ) ) {
/ / par a cada l l amada asoci ada al t el f ono cr ea
/ / un j avabean Ll amadaBean y l o r el l ena con l os
/ / dat os de l a mi sma
82 STRUTS RA-MA

Ll amadaBean l l amada=new Ll amadaBean( ) ;
l l amada. set Tel ef ono( t el ef ono) ;
l l amada. set Dest i no( r s. get I nt ( " dest i no" ) ) ;
l l amada. set Dur aci on( r s. get I nt ( " dur aci on" ) ) ;
l l amada. set Tar i f a( t hi s. get Tar i f a(
r s. get I nt ( " f ki dt i pot ar i f a" ) ) ) ;
l l amada. set Cost e( r s. get Doubl e( " cost e" ) ) ;
l l amada. set Fecha( r s. get St r i ng( " f echa" ) ) ;
l l amadas. add( l l amada) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n l l amadas;
}
}
//recupera el nombre de una tarifa en la tabla de
//tarifas a partir de su identificador
pr i vat e St r i ng get Tar i f a( i nt i d) {
St r i ng t ar i f a=nul l ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St r i ng quer y = " sel ect nombr et ar i f a f r omt ar i f as " ;
quer y +=" wher e i dt i pot ar i f a=" +i d;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
/ / si exi st e una t ar i f a asoci ada a ese i dent i f i cador
/ / devol ver su nombr e, si no devol ver nul l
i f ( r s. next ( ) ) {
t ar i f a=r s. get St r i ng( " nombr et ar i f a" ) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n t ar i f a;
RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 83

}
}
}
GestionTelefonos.java
package model o;

i mpor t j ava. sql . *;
i mpor t j ava. ut i l . *;
publ i c cl ass Gest i onTel ef onos {
Dat os dt ;
publ i c Gest i onTel ef onos( St r i ng dr i ver , St r i ng cadenacon)
{
dt =new Dat os( dr i ver , cadenacon) ;
}
//devuelve una coleccin con todos los telfonos
//asociados al usuario
publ i c Ar r ayLi st <I nt eger > get Tel ef onos( St r i ng passwor d) {
Ar r ayLi st <I nt eger > numer os=
new Ar r ayLi st <I nt eger >( ) ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St r i ng quer y = " sel ect t el ef ono f r om
t el ef onos wher e f kpasswor d =' " ;
quer y+=passwor d+" ' " ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
whi l e( r s. next ( ) ) {
numer os. add( r s. get I nt ( " t el ef ono" ) ) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n numer os;
}
}
}
84 STRUTS RA-MA

opciones.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- bean"
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1>Li st ado de t el f onos del usuar i o</ h1>
<ht ml : f or mact i on=" / l i st ado" met hod=" POST" >
<b> Sel ecci one nmer o de t el f ono: </ b>
<br / > <br / >
<ht ml : sel ect pr oper t y=" numer o" >
<! - - Recuper a el bean Val i daci onFor mal macenado
en una var i abl e de pet i ci n- - >
<ht ml : opt i ons name=" Val i daci onFor m"
pr oper t y=" t el ef onos" / >
</ ht ml : sel ect >
<br / > <br / > <br / >
<ht ml : submi t val ue=" Most r ar l i st ado" / >
</ ht ml : f or m>
</ cent er >
</ body>
</ ht ml : ht ml >



RA-MA CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 85

listado.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN" " ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >

<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<%Ar r ayLi st <Ll amadaBean> l l amadas=
( Ar r ayLi st ) r equest . get At t r i but e( " l l amadas" ) ; %>
<h1>Li st ado de Ll amadas</ h1>
<t abl e bor der =" 1" wi dt h=" 60%" >
<t h>Tel f ono dest i no</ t h>
<t h>Dur aci n ( segundos) </ t h>
<t h>Tar i f a</ t h>
<t h>Cost e</ t h>
<t h>Fecha</ t h>
<%f or ( i nt i =0; i <l l amadas. si ze( ) ; i ++) {
Ll amadaBean l l amada=l l amadas. get ( i ) ; %>
<t r >
<t d><%=l l amada. get Dest i no( ) %></ t d>
<t d><%=l l amada. get Dur aci on( ) %></ t d>
<t d><%=l l amada. get Tar i f a( ) %></ t d>
<t d><%=l l amada. get Cost e( ) %></ t d>
<t d><%=l l amada. get Fecha( ) %></ t d>
</ t r >
<%}%>
</ t abl e>
</ cent er >
</ body>
</ ht ml >


4Captulo 4
ANLISIS DEL API DE STRUTS
Despus de ver en accin durante el Captulo anterior a los diferentes
componentes de Struts, a lo largo de los siguientes Captulos vamos a analizar en
detalle estos componentes a fin de poder explotar a fondo todas sus posibilidades.
En este Captulo profundizaremos en el estudio del API de Struts, tanto en
lo que se refiere a los componentes del Controlador como a los J avaBeans de tipo
ActionForm.
4.1 PROCESAMIENTO DE UNA PETICIN: CLASES
ACTIONSERVLET Y REQUESTPROCESSOR
Como ya qued indicado durante el anlisis del Captulo anterior,
ActionServlet representa el punto de entrada a la aplicacin Struts, de tal manera
que todas las peticiones HTTP que llegan desde la capa cliente a la aplicacin son
dirigidas a este servlet.
Una vez recibida la peticin, ActionServlet delega el anlisis y
procesamiento de la misma en un objeto RequestProcessor. Este objeto es el
encargado de realizar todas la operaciones relativas al tratamiento de la peticin
descritas en el Captulo 2, como son el anlisis de la URL de la peticin,
instanciacin y rellenado del ActionForm, determinacin del objeto Action a
ejecutar e invocacin a su mtodo execute(), anlisis del objeto ActionForward
retornado y transferencia de la peticin a la vista correspondiente.
88 STRUTS RA-MA

Cada una de estas tareas es realizada de forma independiente por los
distintos mtodos proporcionados por org.apache.struts.action.RequestProcessor.
Estos mtodos tienen una implementacin por defecto que, normalmente, suele ser
adecuada en la mayora de los escenarios. No obstante, el hecho de que cada tarea
sea tratada por un mtodo diferente permite al programador personalizar de manera
individualizada estas operaciones, creando subclases de RequestProcessor en los
que sobrescribiremos nicamente aquellos mtodos cuyo comportamiento
predeterminado nos interese cambiar.
He aqu algunos de los principales mtodos de la clase RequestProcessor.
Los analizaremos segn el orden en que son ejecutados:
processPath(). Analiza la URL de la peticin y obtiene el path que
ser utilizado para determinar la accin a ejecutar.
processPreprocess(). Indica si se continuar o no procesando la
peticin despus de que este mtodo se haya ejecutado. En su
implementacin por defecto processPreprocess() nicamente tiene
como funcin devolver el valor true para que la peticin siga
procesndose, es por ello que si el programador desea introducir
algn tipo de control en funcin del cual el procesamiento de la
peticin pueda ser cancelado, la sobrescritura de este mtodo
constituye una buena opcin.
processMapping(). A partir del path obtenido durante la ejecucin
de processPath(), la implementacin por defecto de este mtodo se
encarga de localizar el elemento <action>correspondiente dentro
del archivo de configuracin struts-config.xml, devolviendo un
objeto ActionMapping asociado al mismo.
processActionForm(). Utilizando el objeto ActionMapping
proporcionado por el mtodo anterior devuelve el objeto
ActionForm asociado a la accin, localizndolo en el mbito
especificado o crendolo si no existiera. En caso de no indicarse
ningn ActionForm en la accin se devolver el valor null.
processPopulate(). Con los datos del formulario cliente,
processPopulate() procede al rellenado del objeto ActionForm
obtenido por el mtodo anterior.
processValidate(). Invoca al mtodo validate() del objeto
ActionForm, una vez que ste ha sido rellenado.
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 89

processActionCreate(). Tras la validacin del formulario, en este
mtodo se procede a la creacin del objeto Action definido en el
ActionMapping.
processActionPerform(). Una vez creado el objeto Action desde
este mtodo se realiza la llamada al mtodo execute() del mismo,
devolviendo como repuesta el objeto ActionForward generado por
ste.
processForwardConfig(). Por ltimo, a partir del objeto
ActionForward anterior y la informacin incluida en el archivo
struts-config.xml, este mtodo se encarga de redirigir al usuario a
la vista correspondiente.









Fig. 20. Ciclo de vida de un objeto RequestProcessor
Para que ActionServlet utilice la subclase de RequestProcessor definida
por el programador en vez de la propia RequestProcessor, es necesario registrar
esta clase en struts-config.xml dentro del elemento <controller>, tal y como se
indica a continuacin:
<st r ut s- conf i g>
:
<act i on- mappi ngs>
:
processPath(){..}
processPreprocess(){..}
processMapping(){..}
processActionForm(){..}
processPopulate(){..}
processValidate(){..}
processActionCreate(){..}
processActionPerform(){..}
processForwardConfig(){..}
ActionServlet
........
struts-config.xml
<
a
c
t
i
o
n
>
ActionForm
validate(){..}
setXxx(){..}
Action
execute(){..}
new
1
2
3
4
5
6
7
8
9
RequestProcessor
90 STRUTS RA-MA

</ act i on- mappi ngs>
<controller processorClass="misclases.MiRequestProcessor"/>
Mediante el atributo processorClass se especifica el nombre cualificado de
la clase, que como el resto de las clases de la aplicacin deber estar ubicada en el
directorio raiz_aplicacion\WEB-INF\classes.
Supongamos por ejemplo que en la aplicacin presentada en la prctica
3.1, un usuario intenta acceder a la pgina de listado de llamadas incluyendo
directamente la URL asociada a esa opcin en su navegador. Al hacerlo se
producir una excepcin en el servidor, envindole al usuario una respuesta con
contenido indeterminado.
Para evitar esta situacin, definiremos una subclase RequestProcessor
personalizada en el que sobrescribiremos el mtodo processPreprocess() de
manera que evite el procesamiento de la peticin en caso de que se intente acceder
a la pgina sin haberse validado.
Lo primero que haremos es modificar la clase ValidarAction para que
almacene en una variable de sesin un dato boolean que nos indique que el usuario
est validado:
i f ( gc. val i dar ( vf ) ) {
Gest i onTel ef onos gt =
new Gest i onTel ef onos( dr i ver , cadenaCon) ;
//recupera los nmeros asociados al password y
//los almacena en el bean ValidacionForm
//para que puedan ser accesibles
//a la vista "bienvenida"
vf . set Tel ef onos(
gt . get Tel ef onos( vf . get Passwor d( ) ) ) ;
/ / guar da en una var i abl e de sesi n
/ / el i ndi cat i vo de que el usuar i o se ha val i dado
r equest . get Sessi on( ) .
set At t r i but e( " val i dado" , t r ue) ;
r et ur n mappi ng. f i ndFor war d( " bi enveni da" ) ;
}
Despus crearemos una subclase de RequestProcessor a la que llamaremos
PreProcesamiento, cuya implementacin ser la siguiente:
package ser vl et s;
i mpor t j avax. ser vl et . ht t p. *;
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 91

i mpor t or g. apache. st r ut s. act i on. *;
i mpor t or g. apache. st r ut s. act i ons. *;

publ i c cl ass Pr ePr ocesami ent o ext ends Request Pr ocessor {
publ i c bool ean pr ocessPr epr ocess( Ht t pSer vl et Request
r equest , Ht t pSer vl et Response r esponse) {
Ht t pSessi on sesi on=r equest . get Sessi on( ) ;
//de esta manera, si se intenta solicitar el
//listado de llamadas sin haberse validado
//previamente, se recibir una pgina en blanco
i f ( r equest . get Ser vl et Pat h( ) .
equal s( " / l i st ado. do" ) &&
sesi on. get At t r i but e( " val i dado" ) ==nul l ) {
r et ur n f al se;
}
el se{
r et ur n t r ue;
}
}
}
Finalmente, habr que registrar esta clase en struts-config.xml para que sea
utilizada por ActionServlet:
<cont r ol l er pr ocessor Cl ass=" ser vl et s. Pr ePr ocesami ent o" / >
4.2 CLASES DE ACCIN
Como norma general, solemos crear subclases de Action para gestionar los
distintos tipos de peticiones que llegan desde el cliente a la aplicacin. Adems de
sta, en el paquete org.apache.struts.actions se incluyen otras clases cuya
utilizacin puede ser ms adecuada en determinadas aplicaciones a la hora de
gestionar ciertos tipos de peticiones, de modo que en vez de crear una subclase de
Action para su tratamiento se creara un subtipo de una de estas otras clases.
Vamos a analizar a continuacin las clases ms interesantes que forman
este paquete.
92 STRUTS RA-MA

4.2.1 Clase DispatchAction
Se trata de una subclase de Action que permite definir en la misma clase
diferentes mtodos para tratar un grupo de peticiones similares, evitando tener
que crear una clase distinta para la gestin de cada accin. Por ejemplo,
supongamos que tenemos que implementar la gestin de las operaciones sobre un
carrito de compra, tales como la insercin de un nuevo elemento en el carrito, la
eliminacin de un elemento existente o la recuperacin de todo su contenido; cada
una de estas operaciones se llevar a cabo como respuesta a una peticin distinta
desde el cliente. Pues bien, en vez de implementar tres subclases de Action para su
tratamiento, crearemos una nica subclase de DispatchAction con tres mtodos que
asociaremos a cada una de estas peticiones; el programador es libre de elegir el
nombre de estos mtodos, siempre y cuando tengan el mismo formato que el
mtodo execute() de Action. El siguiente listado corresponde a una clase de
ejemplo para la gestin de peticiones sobre el carrito:
public class GestionCarritoAction extends DispatchAction{
public ActionForward insertarItem(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response){
//mtodo que lleva a cabo la insercin de un elemento
//en el carrito
}
public ActionForward eliminarItem(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response){
//mtodo que lleva a cabo la eliminacin de un elemento
//en el carrito
}
public ActionForward obtenerItems(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response){
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 93

//mtodo que lleva a cabo la recuperacin
//del contenido completo del carrito
}
}
Como vemos, la subclase de DispatchAction no necesita sobrescribir el
mtodo execute(), de hecho no debe sobrescribirse ya que es la implementacin por
defecto de este mtodo incluida en DispatchAction la encargada de determinar el
mtodo a ejecutar segn la peticin realizada.
En este caso, las tres peticiones deben provocar la ejecucin del mismo
tipo de objeto (GestionCarritoAction) por lo que las tres debern incluir el mismo
path asociado, por ejemplo gestioncarrito.do. Ser a travs de un parmetro
enviado en la peticin como el mtodo execute() podr determinar cul de los
mtodos definidos en la clase para la gestin de las acciones ha de ser ejecutado. El
nombre de este parmetro ser elegido por el programador y su valor en cada
peticin tendr que coincidir exactamente con el nombre del mtodo que se
quiera ejecutar (figura 21).








Fig. 21. Equivalencia entre valores de parmetro y mtodos
Por ejemplo, si elegimos operacion como nombre de parmetro las
siguientes URL provocarn la ejecucin de los mtodos insertarItem(),
eliminarItem() y obtenerItems(), respectivamente, definidos en la clase
GestionCarrito indicada anteriormente:
publicclassSubclaseDispatchActionextends
DispatchAction{
publicActionForwardmetodo1(...){..}
publicActionForwardmetodo2(...){..}
publicActionForwardmetodo3(...){..}
}
direccion.do?
parametro=metodo1
parametro=metodo2
parametro=metodo3
94 STRUTS RA-MA

http://miservidor/miaplicacion/gestioncarrito.do?operacion=insertarItem
http://miservidor/miaplicacion/gestioncarrito.do?operacion=eliminarItem
http://miservidor/miaplicacion/gestioncarrito.do?operacion=obtenerItems
El parmetro que determina el nombre del mtodo a ejecutar no tiene que ir
necesariamente insertado en la URL, podra emplearse cualquier control del
formulario enviado en la peticin. Los posibles valores de este control seran
entonces los que determinaran el mtodo que debe ser ejecutado.
El nombre del parmetro o control deber quedar especificado en la
configuracin del elemento <action>de struts-config.xml a travs de su atributo
parameter. En el ejemplo que estamos analizando la configuracin de este
elemento para la gestin de peticiones relativas al carrito de la compra quedara
como se indica a continuacin:
<action path="/gestioncarrito"
type="misclases.GestionCarritoAction"
parameter="operacion"/>
En la definicin de este elemento de ejemplo hemos omitido los
parmetros name y scope por ser irrelevantes para el tema que estamos tratando,
sin embargo en un caso real deberan ser especificados si la aplicacin hace uso de
algn objeto ActionForm.
PRCTICA 4.1. OPCIONES PARA LISTADO DE LLAMADAS DEL
USUARIO
Descripcin
Se trata de realizar una versin ampliada de la aplicacin desarrollada en la
prctica 3.1 del Captulo anterior. En esta nueva versin proporcionaremos al
usuario una serie de opciones de cara a visualizar el listado de llamadas de un
nmero, opciones que consistirn en la posibilidad de elegir el tipo de llamadas a
visualizar, pudiendo optar por visualizar todas las llamadas, aquellas que
correspondan a un determinado tipo o las realizadas a partir de una determinada
fecha.
La figura 22 muestra el nuevo aspecto que tendr ahora la pgina de
opciones de la aplicacin, una vez que el usuario se ha validado.
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 95









Fig. 22. Aspecto de la pgina de opciones
Desarrollo
En vez de crear una clase Action por cada opcin a gestionar, utilizaremos
una nica clase DispatchAction con tres mtodos, uno para cada opcin. A travs
del parmetro llamado operacion generado por los botones de radio enviaremos
al servidor el nombre del mtodo a ejecutar para cada opcin elegida.
Tanto el nmero de telfono, como la opcin elegida, as como los datos
adicionales asociados a cada una, sern encapsulados en el bean OpcionesForm.
Por otro lado, ser necesario implementar un nuevo bean, llamado Tarifa,
que encapsule los datos asociados a las tarifas. Este J avaBean ser utilizado para
generar la lista de tarifas, cuyos datos sern mostrados en la lista desplegable
asociada al tipo de llamada.
Listado
Los siguientes listados corresponden a los nuevos elementos
implementados en esta versin de la aplicacin, as como a aquellos que han sido
modificados, indicando en este caso en fondo sombreado los cambios introducidos.


96 STRUTS RA-MA

sruts-config.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE st r ut s- conf i g PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s
Conf i gur at i on 1. 2/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/ st r ut s-
conf i g_1_2. dt d" >
<st r ut s- conf i g>
<f or m- beans>
<f or m- bean name=" Opci onesFor m"
t ype=" j avabeans. Opci onesFor m" / >
<f or m- bean name=" Regi st r oFor m"
t ype=" j avabeans. Regi st r oFor m" / >
<f or m- bean name=" Val i daci onFor m"
t ype=" j avabeans. Val i daci onFor m" / >

</ f or m- beans>

<gl obal - f or war ds>
<f or war d name=" l ogi n" pat h=" / l ogi n. j sp" / >
<f or war d name=" t or egi st r o" pat h=" / r egi st r o. j sp" / >
</ gl obal - f or war ds>

<act i on- mappi ngs>
<act i on i nput =" / " name=" Val i daci onFor m"
pat h=" / val i dar " scope=" r equest "
t ype=" ser vl et s. Val i dar Act i on" >
<f or war d name=" bi enveni da" pat h=" / opci ones. j sp" / >
<f or war d name=" er r or " pat h=" / l ogi n. j sp" / >
</ act i on>
<act i on i nput =" / r egi st r o. j sp" name=" Regi st r oFor m"
pat h=" / r egi st r ar " scope=" r equest "
t ype=" ser vl et s. Regi st r ar Act i on" >
<f or war d name=" r egi st r ado" pat h=" / l ogi n. j sp" / >
</ act i on>




RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 97

<act i on pat h=" / l i st ado" name=" Opci onesFor m"
t ype=" ser vl et s. Li st adoAct i on"
par amet er =" oper aci on" >
<f or war d name=" l i st ado" pat h=" / l i st ado. j sp" / >
</ act i on>
</ act i on- mappi ngs>
</ st r ut s- conf i g>

Tarifa.java
package j avabeans;

publ i c cl ass Tar i f a {
pr i vat e i nt i dt i pot ar i f a;
pr i vat e St r i ng nombr et ar i f a;
publ i c i nt get I dt i pot ar i f a( ) {
r et ur n i dt i pot ar i f a;
}
publ i c voi d set I dt i pot ar i f a( i nt i dt i pot ar i f a) {
t hi s. i dt i pot ar i f a = i dt i pot ar i f a;
}
publ i c St r i ng get Nombr et ar i f a( ) {
r et ur n nombr et ar i f a;
}
publ i c voi d set Nombr et ar i f a( St r i ng nombr et ar i f a) {
t hi s. nombr et ar i f a = nombr et ar i f a;
}
}
OpcionesForm.java
package j avabeans;

i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;

publ i c cl ass Opci onesFor mext ends Act i onFor m{
pr i vat e i nt numer o;
pr i vat e St r i ng oper aci on;
pr i vat e i nt t i po;
pr i vat e St r i ng f echa;
98 STRUTS RA-MA

publ i c i nt get Numer o( ) {
r et ur n numer o;
}
publ i c voi d set Numer o( i nt i ) {
numer o = i ;
}
publ i c St r i ng get Oper aci on( ) {
r et ur n oper aci on;
}
publ i c voi d set Oper aci on( St r i ng oper aci on) {
t hi s. oper aci on = oper aci on;
}
publ i c i nt get Ti po( ) {
r et ur n t i po;
}
publ i c voi d set Ti po( i nt t i po) {
t hi s. t i po = t i po;
}
publ i c St r i ng get Fecha( ) {
r et ur n f echa;
}
publ i c voi d set Fecha( St r i ng f echa) {
t hi s. f echa = f echa;
}
}
GestionTelefonos.java
package model o;

i mpor t j ava. sql . *;
i mpor t j ava. ut i l . *;
i mpor t j avabeans. Tar i f a;
publ i c cl ass Gest i onTel ef onos {

Dat os dt ;
publ i c Gest i onTel ef onos( St r i ng dr i ver ,
St r i ng cadenacon) {
dt =new Dat os( dr i ver , cadenacon) ;
}
publ i c Ar r ayLi st <I nt eger > get Tel ef onos( St r i ng passwor d) {
Ar r ayLi st <I nt eger > numer os=new Ar r ayLi st <I nt eger >( ) ;
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 99

t r y{
Connect i on cn=dt . get Conexi on( ) ;
//instruccin SQL para obtener los datos
//del usuario indicado
St r i ng quer y = " sel ect t el ef ono f r omt el ef onos " ;
quer y+=" wher e passwor d =' " +passwor d+" ' " ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
whi l e( r s. next ( ) ) {
numer os. add( r s. get I nt ( " t el ef ono" ) ) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n numer os;
}
}

publ i c Ar r ayLi st <Tar i f a> get Tar i f as( ) {
Ar r ayLi st <Tar i f a> t ar i f as=new Ar r ayLi st <Tar i f a>( ) ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
Tar i f a t f =nul l ;
/ / i nst r ucci n SQL par a obt ener t odos
/ / l os t i pos de t ar i f as
St r i ng quer y = " sel ect * f r omt ar i f as" ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
whi l e( r s. next ( ) ) {
t f =new Tar i f a( ) ;
t f . set I dt i pot ar i f a( r s. get I nt ( " i dt i pot ar i f a" ) ) ;
t f . set Nombr et ar i f a(
r s. get St r i ng( " nombr et ar i f a" ) ) ;
t ar i f as. add( t f ) ;
}
dt . ci er r aConexi on( cn) ;
}

100 STRUTS RA-MA

cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}

f i nal l y{
r et ur n t ar i f as;
}
}
}
GestionLlamadas.java
package model o;

i mpor t j ava. sql . *;
i mpor t j ava. ut i l . *;
i mpor t j avabeans. *;
i mpor t j ava. t ext . *;
publ i c cl ass Gest i onLl amadas {
Dat os dt ;
publ i c Gest i onLl amadas( St r i ng dr i ver , St r i ng cadenacon) {
dt =new Dat os( dr i ver , cadenacon) ;
}
publ i c Ar r ayLi st <Ll amadaBean> get TodasLl amadasTel ef ono(
i nt t el ef ono) {
St r i ng quer y = " sel ect * f r oml l amadas wher e " ;
quer y+=" t el ef ono=" +t el ef ono;
r et ur n get Ll amadas( quer y, t el ef ono) ;
}
publ i c Ar r ayLi st <Ll amadaBean>
get Ll amadasTel ef onoPor Ti poTar i f a( i nt t el ef ono,
i nt i dt i pot ar i f a) {
St r i ng quer y = " sel ect * f r oml l amadas wher e " ;
quer y+=" t el ef ono=" +t el ef ono+
" and i dt i pot ar i f a=" +i dt i pot ar i f a;
r et ur n get Ll amadas( quer y, t el ef ono) ;
}
//mtodo que obtiene las llamadas, comn para los dos
//mtodos anteriores
pr i vat e Ar r ayLi st <Ll amadaBean> get Ll amadas( St r i ng sql ,
i nt t el ef ono) {

RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 101

Ar r ayLi st <Ll amadaBean> l l amadas=
new Ar r ayLi st <Ll amadaBean>( ) ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( sql ) ;
whi l e( r s. next ( ) ) {
Ll amadaBean l l amada=new Ll amadaBean( ) ;
l l amada. set Tel ef ono( t el ef ono) ;
l l amada. set Dest i no( r s. get I nt ( " dest i no" ) ) ;
l l amada. set Dur aci on( r s. get I nt ( " dur aci on" ) ) ;
l l amada. set Tar i f a( t hi s. get Tar i f a(
r s. get I nt ( " i dt i pot ar i f a" ) ) ) ;
l l amada. set Cost e( r s. get Doubl e( " cost e" ) ) ;
l l amada. set Fecha( r s. get St r i ng( " f echa" ) ) ;
l l amadas. add( l l amada) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n l l amadas;
}
}

publ i c Ar r ayLi st <Ll amadaBean>
get Ll amadasTel ef onoApar t i r Fecha( i nt t el ef ono,
St r i ng f echa) {
Ar r ayLi st <Ll amadaBean> l l amadas=
new Ar r ayLi st <Ll amadaBean>( ) ;
Dat eFor mat f eur opa=Dat eFor mat . get Dat eI nst ance(
Dat eFor mat . SHORT, Local e. get Def aul t ( ) ) ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St r i ng quer y = " sel ect * f r oml l amadas wher e " ;
quer y+=" t el ef ono=" +t el ef ono;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;

102 STRUTS RA-MA

whi l e( r s. next ( ) ) {
//convierte las dos fechas a un formato comn
//para poder compararlas
j ava. ut i l . Dat e f echal l amada=r s. get Dat e( " f echa" ) ;
j ava. ut i l . Dat e f echacompar aci on=
f eur opa. par se( f echa) ;
/ / al macena en el Ar r ayLi st ni cament e l as
/ / l l amadas cuya f echa sea post er i or a l a
/ / sumi ni st r ada como par met r o
i f ( f echal l amada. af t er ( f echacompar aci on) ) {
Ll amadaBean l l amada=new Ll amadaBean( ) ;
l l amada. set Tel ef ono( t el ef ono) ;
l l amada. set Dest i no( r s. get I nt ( " dest i no" ) ) ;
l l amada. set Dur aci on( r s. get I nt ( " dur aci on" ) ) ;
l l amada. set Tar i f a( t hi s. get Tar i f a(
r s. get I nt ( " i dt i pot ar i f a" ) ) ) ;
l l amada. set Cost e( r s. get Doubl e( " cost e" ) ) ;
l l amada. set Fecha(
f eur opa. f or mat ( f echal l amada) ) ;
l l amadas. add( l l amada) ;
}
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n l l amadas;
}
}
pr i vat e St r i ng get Tar i f a( i nt i d) {
St r i ng t ar i f a=nul l ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St r i ng quer y = " sel ect nombr et ar i f a f r omt ar i f as " ;
quer y +=" wher e i dt i pot ar i f a=" +i d;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;


RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 103

i f ( r s. next ( ) ) {
t ar i f a=r s. get St r i ng( " nombr et ar i f a" ) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}

f i nal l y{
r et ur n t ar i f a;
}
}
}
ListadoAction.java
package ser vl et s;

i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t or g. apache. st r ut s. act i ons. *;

i mpor t j avabeans. *;
i mpor t model o. *;
i mpor t j ava. ut i l . *;
publ i c cl ass Li st adoAct i on ext ends Di spat chAct i on {
publ i c Act i onFor war d t odas( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Opci onesFor mof =( Opci onesFor m) f or m;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
r equest . set At t r i but e( " l l amadas" ,
gl . get TodasLl amadasTel ef ono( of . get Numer o( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " l i st ado" ) ;
}
publ i c Act i onFor war d por t i po( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
104 STRUTS RA-MA

t hr ows Except i on {
Opci onesFor mof =( Opci onesFor m) f or m;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
r equest . set At t r i but e( " l l amadas" ,
gl . get Ll amadasTel ef onoPor Ti poTar i f a(
of . get Numer o( ) , of . get Ti po( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " l i st ado" ) ;
}

publ i c Act i onFor war d por f echa( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Opci onesFor mof =( Opci onesFor m) f or m;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
r equest . set At t r i but e( " l l amadas" ,
gl . get Ll amadasTel ef onoApar t i r Fecha(
of . get Numer o( ) , of . get Fecha( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " l i st ado" ) ;
}

pr i vat e Gest i onLl amadas get Gest i onLl amadas(
Ht t pSer vl et Request r equest ) {
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
r et ur n new Gest i onLl amadas( dr i ver , cadenaCon) ;
}
}
opciones.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>
<%@ t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- ht ml "
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 105

" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1>Opci ones par a el l i st ado de l l amadas </ h1>
<ht ml : f or mact i on=" / l i st ado" met hod=" POST" >
<b> Sel ecci one nmer o de t el f ono: </ b>
<br / > <br / >
<ht ml : sel ect pr oper t y=" numer o" >
<! - - Recuper a el bean Val i daci onFor m
al macenado en una var i abl e de pet i ci n- - >
<ht ml : opt i ons name=" Val i daci onFor m"
pr oper t y=" t el ef onos" / >
</ ht ml : sel ect >
<br / > <br / > <br / >
<b>Sel ecci one t i po de l l amadas: </ b><br / >
<t abl e>
<t r >
<t d><ht ml : r adi o t abi ndex=" 0"
pr oper t y=" oper aci on" val ue=" t odas" / >
</ t d><t d al i gn=" l ef t " >Todas</ t d>
</ t r >
<t r >
<t d><ht ml : r adi o pr oper t y=" oper aci on"
val ue=" por t i po" / ></ t d>
<t d al i gn=" l ef t " >Sel ecci one Ti po:
<ht ml : sel ect pr oper t y=" t i po" >
<!--Recupera el ArrayList de tarifas
almacenada en una variable de peticin-->
<ht ml : opt i onsCol l ect i on
name=" Val i daci onFor m"
pr oper t y=" t el ef onos"
val ue=" i dt i pot ar i f a"
l abel =" nombr et ar i f a" / >
</ ht ml : sel ect >
</ t d>
106 STRUTS RA-MA

</ t r >
<t r >
<t d><ht ml : r adi o pr oper t y=" oper aci on"
val ue=" por f echa" / ></ t d>
<t d al i gn=" l ef t " >A par t i r de f echa:
<ht ml : t ext pr oper t y=" f echa" / ></ t d>
</ t r >
<t r >
<t d col span=" 2" ><br / >
<ht ml : submi t val ue=" Most r ar l i st ado" / >
</ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
</ cent er >
</ body>
</ ht ml : ht ml >
4.2.2 Clase LookupDispatchAction
Se trata de una subclase de DispatchAction que, al igual que sta, tiene
como misin gestionar varias peticiones en una misma clase mediante la definicin
de un mtodo personalizado para cada accin, utilizndose el valor de un
parmetro enviado con cada peticin para determinar el mtodo que se tiene que
ejecutar.
A diferencia de DispatchAction, donde el valor del parmetro contiene
directamente el nombre del mtodo asociado a la accin, LookupDispatchAction
utiliza el valor de este parmetro para localizar en el archivo de recursos
ApplicationResource.properties una clave asociada al mismo entre todas las parejas
clave=valor almacenadas. A partir de este dato el objeto recupera el nombre real
del mtodo que tiene que ejecutar, para ello tendr que acceder a una tabla de tipo
Map donde se encuentran almacenados los nombres de los mtodos del objeto con
sus correspondientes claves asociadas (figura 23).
La implementacin por defecto del mtodo execute() existente en
LookupDispatchAction invoca al mtodo getKeyMethodMap() de la propia clase
para obtener el mapa de mtodos con sus correspondientes claves. Es
responsabilidad del programador sobrescribir este mtodo e incluir en l las
instrucciones apropiadas para generar esta coleccin.

RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 107












Fig. 23. Tratamiento de peticiones con LookUpDispatchAction
Por ejemplo, volvamos al caso de la clase GestionCarritoAction
comentada anteriormente y supongamos que queremos asociar los siguientes
valores del parmetro operacin: opcion1, opcion2 y opcion3 a los mtodos
insertarItem(), eliminarItem() y obtenerItems(), respectivamente. Lo primero que
debemos hacer es asignar una clave a cada uno de los valores posibles del
parmetro, por ejemplo:
oper.insertar=opcion1
oper.eliminar=opcion2
oper.recuperar=opcion3
Las lneas anteriores se incluirn dentro del archivo de recursos
ApplicationResource.properties de la aplicacin Web.
A continuacin debemos implementar el mtodo getKeyMethodMap() en la
clase GestionCarritoAction, de manera que genere una tabla Map con los nombres
de los mtodos de la clase utilizando como claves las definidas anteriormente en el
:
publicActionForwardnombre_metodo1(...){..}
publicActionForwardnombre_metodo2(...){..}
:
direccion.do?
parametro=key1
parametro=key2
key1=clave_metodo1
key2=clave_metodo2
clave_metodo1 nombre_metodo1
clave_metodo2 nombre_metodo2
ApplicationResource.properties
Tabla Map
Objeto
LookUpDispatchAction
Recuperacin
de la clave
Recuperacin
del nombre de
mtodo
Llamada al
mtodo
1
2
3
4
108 STRUTS RA-MA

archivo de recursos. Esta ser la nueva implementacin de la clase
GestionCarritoAction:
public class GestionCarritoAction extends LookupDispatchAction{
public Map getKeyMethodMap(){
//definicin de mapa de mtodos
Map mp=new HashMap();
mp.put("opcion.insertar","insertarItem");
mp.put("opcion.eliminar","eliminarItem");
mp.put("opcion.recuperar","obtenerItems");
return mp;
}
public ActionForward insertarItem(...){
//mtodo que lleva a cabo la insercin de un elemento
//en el carrito
}
public ActionForward eliminarItem(...){
//mtodo que lleva a cabo la eliminacin de un elemento
//en el carrito
}
public ActionForward obtenerItems(...){
//mtodo que lleva a cabo la recuperacin
//del contenido completo del carrito
}
}
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 109

Este desacoplamiento entre los nombres de los mtodos y los valores del
parmetro enviado en la peticin permite que puedan ser modificados los valores
de ste sin necesidad de alterar el cdigo de la aplicacin, tan slo habr que hacer
los cambios pertinentes en el archivo ApplicationResource.properties.
Al igual que sucede en el caso DispatchAction, en el registro del elemento
<action>asociado al objeto LookupDispatchAction habr que especificar en el
atributo parameter el nombre del parmetro enviado en la peticin.
Como ejemplo de utilizacin de esta clase, vamos a gestionar las opciones
del listado de llamadas de la aplicacin de la prctica 4.1 mediante un objeto
LookupDispatchAction. Lo primero ser aadir las siguientes cadenas con sus
claves al archivo ApplicationResource.properties:
opcion.todas=todas
opcion.portipo=tipo
opcion.porfecha=fecha
El cdigo de la clase ListadoAction sera prcticamente igual a la de la
prctica 4.1, aadiendo simplemente la implementacin del mtodo
getKeyMethodMap():
package ser vl et s;

i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t or g. apache. st r ut s. act i ons. *;

i mpor t j avabeans. *;
i mpor t model o. *;
i mpor t j ava. ut i l . *;
publ i c cl ass Li st adoAct i on ext ends Di spat chAct i on {
publ i c Map get KeyMet hodMap( ) {
//definicin de mapa de mtodos con sus
// correspondientes claves
Map mp=new HashMap( ) ;
mp. put ( " opci on. t odas" , " t odas" ) ;
mp. put ( " opci on. por t i po" , " por t i po" ) ;
mp. put ( " opci on. por f echa" , " por f echa" ) ;
r et ur n mp;
110 STRUTS RA-MA

}
publ i c Act i onFor war d t odas( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Opci onesFor mof =( Opci onesFor m) f or m;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
r equest . set At t r i but e( " l l amadas" ,
gl . get TodasLl amadasTel ef ono( of . get Numer o( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " l i st ado" ) ;
}
publ i c Act i onFor war d por t i po( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Opci onesFor mof =( Opci onesFor m) f or m;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
r equest . set At t r i but e( " l l amadas" ,
gl . get Ll amadasTel ef onoPor Ti poTar i f a(
of . get Numer o( ) , of . get Ti po( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " l i st ado" ) ;
}
publ i c Act i onFor war d por f echa( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Opci onesFor mof =( Opci onesFor m) f or m;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
r equest . set At t r i but e( " l l amadas" ,
gl . get Ll amadasTel ef onoApar t i r Fecha(
of . get Numer o( ) , of . get Fecha( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " l i st ado" ) ;
}
pr i vat e Gest i onLl amadas get Gest i onLl amadas(
Ht t pSer vl et Request r equest ) {
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 111

get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
r et ur n new Gest i onLl amadas( dr i ver , cadenaCon) ;
}
}
En cuanto a la pgina opciones.jsp, tan slo modificaramos los valores del
parmetro operaciones (para que no tengan por qu coincidir con los nombres de
los mtodos), segn lo indicado en el archivo ApplicationResource.properties:
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1>Opci ones par a el l i st ado de l l amadas </ h1>
<ht ml : f or mact i on=" / l i st ado" met hod=" POST" >
<b> Sel ecci one nmer o de t el f ono: </ b>
<br / > <br / >
<ht ml : sel ect pr oper t y=" numer o" >
<!--Recupera el bean ValidacionForm
almacenado en una variable de peticin-->
<ht ml : opt i ons name=" Val i daci onFor m"
pr oper t y=" t el ef onos" / >
</ ht ml : sel ect >
<br / > <br / > <br / >
<b>Sel ecci one t i po de l l amadas: </ b><br / >
<t abl e>
<t r >
<t d><ht ml : r adi o t abi ndex=" 0"
pr oper t y=" oper aci on" val ue=" t odas" / >
112 STRUTS RA-MA

</ t d><t d al i gn=" l ef t " >Todas</ t d>
</ t r >
<t r >
<t d><ht ml : r adi o pr oper t y=" oper aci on"
val ue=" t i po" / ></ t d>
<t d al i gn=" l ef t " >Sel ecci one Ti po:
<ht ml : sel ect pr oper t y=" t i po" >
<!--Recupera el ArrayList de tarifas
almacenada en una variable de peticin-->
<ht ml : opt i onsCol l ect i on
name=" Val i daci onFor m"
pr oper t y=" t el ef onos"
val ue=" i dt i pot ar i f a"
l abel =" nombr et ar i f a" / >
</ ht ml : sel ect >
</ t d>
</ t r >
<t r >
<t d><ht ml : r adi o pr oper t y=" oper aci on"
val ue=" f echa" / ></ t d>
<t d al i gn=" l ef t " >A par t i r de f echa:
<ht ml : t ext pr oper t y=" f echa" / ></ t d>
</ t r >
<t r >
<t d col span=" 2" ><br / >
<ht ml : submi t val ue=" Most r ar l i st ado" / >
</ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
</ cent er >
</ body>
</ ht ml : ht ml >
4.2.3 Clase MappingDispatchAction
Se trata tambin de una subclase de DispatchAction que, al igual que las
anteriores, permite definir en la misma clase un grupo de mtodos para la gestin
de peticiones diferentes.
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 113

En este caso no se utiliza ningn parmetro que permita determinar el
mtodo a ejecutar, sino que cada peticin utilizar un path diferente para acceder al
mismo objeto, lo que obligar a definir en el struts-config.xml tantos elementos
<action> asociados a la misma subclase de MappingDispatchAction como
peticiones distintas deba gestionar el objeto. Utilizando el atributo parameter del
elemento <action> se indicar para cada peticin el nombre del mtodo que se
debe ejecutar, consiguiendo as el desacoplamiento entre el path y el nombre del
mtodo (figura 24).









Fig. 24. Tratamiento de peticiones con MappingDispatchAction
Para entender el funcionamiento volvamos al ejemplo del carrito de la
compra que hemos utilizado con las clases anteriores. Supongamos que tenemos
tres enlaces en la pgina cliente que lanzan las peticiones para la realizacin de las
tres operaciones descritas sobre el carrito:
<a href="agregar.do">Aadir elemento</a>
<a href="eliminar.do">Eliminar elemento</a>
<a href="recuperar.do">Recuperar contenido</a>
:
public ActionForward metodo1(...){..}
public ActionForward metodo2(...){..}
:
direccion1.do
direccion2.do
<action path=/direccion1
parameter=metodo1/>
<action path=/direccion2
parameter=metodo2/>
struts-config.xml
Objeto
MappingDispatchAction
Recuperacin
del nombre de
mtodo
Llamada al
mtodo
1
2
3
114 STRUTS RA-MA

Para que las tres peticiones provoquen la ejecucin del objeto
GestionCarritoAction deberamos registrar los siguientes elementos <action>en el
archivo struts-config.xml:
<act i on pat h=" agr egar " t ype=" mi scl ases. Gest i onCar r i t oAct i on"
par amet er =" i nser t ar I t em" / >
<act i on pat h=" el i mi nar " t ype=" mi scl ases. Gest i onCar r i t oAct i on"
par amet er =" el i mi nar I t em" / >
<act i on pat h=" r ecuper ar "
t ype=" mi scl ases. Gest i onCar r i t oAct i on"
par amet er =" obt ener I t ems" / >
Los valores indicados en el atributo parameter de cada elemento <action>
anterior representan los nombres de los mtodos de la clase GestionCarritoAction
asociados a cada accin. La estructura de esta clase ser ahora la que se indica en el
siguiente listado:
public class GestionCarritoAction extends MappingDispatchAction{
public ActionForward insertarItem(...){
//mtodo que lleva a cabo la insercin de un elemento
//en el carrito
}
public ActionForward eliminarItem(...){
//mtodo que lleva a cabo la eliminacin de un elemento
//en el carrito
}
public ActionForward obtenerItems(...){
//mtodo que lleva a cabo la recuperacin
//del contenido completo del carrito
}
}
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 115

PRCTICA 4.2. INFORMACIN TELEFNICA
Descripcin
La presente prctica consistir en la implementacin de una variante de la
aplicacin desarrollada en la prctica 4.1. En esta ocasin, una vez validado el
usuario, se le presentar una pgina de opciones de informacin que le permitirn
acceder a la lista de telfonos registrados a su nombre, conocer el consumo
acumulado o visualizar el histrico de llamadas. La figura 25 ilustra las pginas de
la aplicacin, sin incluir las de validacin y registro.









Fig. 25. Pginas de la aplicacin
Desarrollo
La gestin de las opciones ser llevada a cabo por la clase OpcionesAction
que en este caso ser una subclase de MappingDispatchAction con tres mtodos
asociados a cada uno de los enlaces de la pgina opciones.jsp, asociacin que como
hemos indicado se realizar en cada elemento <action>de struts-config.xml.
Por otro lado, se ha modificado el mbito del objeto ValidacionForm,
pasando de request a session. De esta manera, ser posible tener acceso al login de
usuario desde la pgina factura.jsp a fin de personalizar el mensaje mostrado al
usuario.
116 STRUTS RA-MA

Listado
Seguidamente mostraremos el cdigo de los nuevos elementos
desarrollados en esta prctica, as como las modificaciones realizadas en los ya
creados.
struts-config.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>

<! DOCTYPE st r ut s- conf i g PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s
Conf i gur at i on 1. 2/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/ st r ut s-
conf i g_1_2. dt d" >
<st r ut s- conf i g>
<f or m- beans>
<f or m- bean name=" Opci onesFor m"
t ype=" j avabeans. Opci onesFor m" / >
<f or m- bean name=" Regi st r oFor m"
t ype=" j avabeans. Regi st r oFor m" / >
<f or m- bean name=" Val i daci onFor m"
t ype=" j avabeans. Val i daci onFor m" / >

</ f or m- beans>
<gl obal - f or war ds>
<f or war d name=" l ogi n" pat h=" / l ogi n. j sp" / >
<f or war d name=" t or egi st r o" pat h=" / r egi st r o. j sp" / >
</ gl obal - f or war ds>
<act i on- mappi ngs>
<!--se define como mbito de sesin para que
siempre pueda recordar qu usuario
es durante toda la navegacin-->
<act i on i nput =" / " name=" Val i daci onFor m"
pat h=" / val i dar " scope=" sessi on"
t ype=" ser vl et s. Val i dar Act i on" >
<f or war d name=" bi enveni da" pat h=" / opci ones. j sp" / >
<f or war d name=" er r or " pat h=" / l ogi n. j sp" / >
</ act i on>
<act i on i nput =" / r egi st r o. j sp" name=" Regi st r oFor m"
pat h=" / r egi st r ar " scope=" r equest "
t ype=" ser vl et s. Regi st r ar Act i on" >
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 117

<f or war d name=" r egi st r ado" pat h=" / l ogi n. j sp" / >
</ act i on>
<act i on pat h=" / f act ur aci on"
t ype=" ser vl et s. Opci onesAct i on"
par amet er =" f act ur a" >
<f or war d name=" vi st af act ur a"
pat h=" / f act ur a. j sp" / >
</ act i on>
<act i on pat h=" / numer os"
t ype=" ser vl et s. Opci onesAct i on"
par amet er =" numer os" >
<f or war d name=" vi st anumer os"
pat h=" / numer os. j sp" / >
</ act i on>
<act i on pat h=" / det al l es"
t ype=" ser vl et s. Opci onesAct i on"
par amet er =" det al l es" >
<f or war d name=" vi st adet al l es"
pat h=" / det al l es. j sp" / >
</ act i on>
</ act i on- mappi ngs>
</ st r ut s- conf i g>
GestionLlamadas.java
package model o;

i mpor t j ava. sql . *;
i mpor t j ava. ut i l . *;
i mpor t j avabeans. *;
i mpor t j ava. t ext . *;
publ i c cl ass Gest i onLl amadas {
Dat os dt ;
publ i c Gest i onLl amadas( St r i ng dr i ver , St r i ng cadenacon) {
dt =new Dat os( dr i ver , cadenacon) ;
}
publ i c Ar r ayLi st <Ll amadaBean> get Ll amadas(
St r i ng passwor d) {
St r i ng quer y = " sel ect * f r oml l amadas wher e " ;
quer y+=" t el ef ono i n ( sel ect t el ef ono f r om
t el ef onos wher e " ;
quer y+=" passwor d =' " +passwor d+" ' ) or der by t el ef ono" ;
118 STRUTS RA-MA

r et ur n get Li st ado( quer y) ;
}
//mtodo auxiliar de apoyo al anterior
pr i vat e Ar r ayLi st <Ll amadaBean> get Li st ado( St r i ng sql ) {
/ / se ut i l i za par a poder apl i car el f or mat o
/ / de f echa eur opeo
Dat eFor mat f eur opa=Dat eFor mat . get Dat eI nst ance(
Dat eFor mat . SHORT, Local e. get Def aul t ( ) ) ;
Ar r ayLi st <Ll amadaBean> l l amadas=
new Ar r ayLi st <Ll amadaBean>( ) ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( sql ) ;
whi l e( r s. next ( ) ) {
Ll amadaBean l l amada=new Ll amadaBean( ) ;
l l amada. set Tel ef ono( r s. get I nt ( " t el ef ono" ) ) ;
l l amada. set Dest i no( r s. get I nt ( " dest i no" ) ) ;
l l amada. set Dur aci on( r s. get I nt ( " dur aci on" ) ) ;
l l amada. set Tar i f a( t hi s. get Tar i f a(
r s. get I nt ( " i dt i pot ar i f a" ) ) ) ;
l l amada. set Cost e( r s. get Doubl e( " cost e" ) ) ;
l l amada. set Fecha( f eur opa. f or mat (
r s. get Dat e( " f echa" ) ) ) ;
l l amadas. add( l l amada) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n l l amadas;
}
}
publ i c doubl e get Fact ur a( St r i ng passwor d) {
St r i ng quer y = " sel ect sum( cost e) as t ot al f r om
l l amadas wher e " ;
quer y+=" t el ef ono i n ( sel ect t el ef ono f r omt el ef onos " ;
quer y+=" wher e passwor d =' " +passwor d+" ' ) " ;
doubl e t ot al =0. 0;
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 119

t r y{
Connect i on cn=dt . get Conexi on( ) ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
i f ( r s. next ( ) ) {
t ot al =r s. get Doubl e( " t ot al " ) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n t ot al ;
}
}
pr i vat e St r i ng get Tar i f a( i nt i d) {
St r i ng t ar i f a=nul l ;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
St r i ng quer y = " sel ect nombr et ar i f a f r omt ar i f as " ;
quer y +=" wher e i dt i pot ar i f a=" +i d;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
i f ( r s. next ( ) ) {
t ar i f a=r s. get St r i ng( " nombr et ar i f a" ) ;
}
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n t ar i f a;
}
}
}
OpcionesAction.java
package ser vl et s;

120 STRUTS RA-MA

i mpor t j avax. ser vl et . ht t p. *;

i mpor t or g. apache. st r ut s. act i on. *;
i mpor t or g. apache. st r ut s. act i ons. *;
i mpor t j avabeans. *;
i mpor t model o. *;
i mpor t j ava. ut i l . *;

publ i c cl ass Opci onesAct i on ext ends Mappi ngDi spat chAct i on {
publ i c Act i onFor war d f act ur a(
Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Ht t pSessi on sesi on=r equest . get Sessi on( ) ;
Val i daci onFor mvf =( Val i daci onFor m) sesi on.
get At t r i but e( " Val i daci onFor m" ) ;
Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;

r equest . set At t r i but e( " pr eci o" ,
gl . get Fact ur a( vf . get Passwor d( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " vi st af act ur a" ) ;
}
publ i c Act i onFor war d numer os( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
//el FormBean ValidacionForm contiene los telfonos
//asociados al usuario
r et ur n mappi ng. f i ndFor war d( " vi st anumer os" ) ;
}
publ i c Act i onFor war d det al l es( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Ht t pSessi on sesi on=r equest . get Sessi on( ) ;
Val i daci onFor mvf =( Val i daci onFor m) sesi on.
get At t r i but e( " Val i daci onFor m" ) ;
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 121

Gest i onLl amadas gl =get Gest i onLl amadas( r equest ) ;
r equest . set At t r i but e( " l l amadas" ,
gl . get Ll amadas( vf . get Passwor d( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " vi st adet al l es" ) ;
}
pr i vat e Gest i onLl amadas get Gest i onLl amadas(
Ht t pSer vl et Request r equest ) {
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
r et ur n new Gest i onLl amadas( dr i ver , cadenaCon) ;
}
}
opciones.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
<st yl e>
. t d{mar gi n- l ef t : 0px}
</ st yl e>
</ head>
<body>
<cent er >
<h1>Opci ones par a el usuar i o </ h1>
<t abl e>
<t r >
<t d><ht ml : l i nk page=" / numer os. do" >
Most r ar sus numer os
122 STRUTS RA-MA

</ ht ml : l i nk>
</ t d>
</ t r >
<t r >
<t d><ht ml : l i nk page=" / f act ur aci on. do" >
Fact ur aci n t ot al del usuar i o
</ ht ml : l i nk>
</ t d>
</ t r >
<t r >
<t d><ht ml : l i nk page=" / det al l es. do" >
Det al l es de l l amadas
</ ht ml : l i nk>
</ t d>
</ t r >
</ t abl e>
</ cent er >
</ body>
</ ht ml : ht ml >
nomeros.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<br / ><br / >
<h2> Est e usuar i o t i ene cont r at ados
l os si gui ent es nmer os: <br / ><br / >
<%Ar r ayLi st <I nt eger > l i st a=
( ( Val i daci onFor m) sessi on.
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 123

get At t r i but e( " Val i daci onFor m" ) ) .
get Tel ef onos( ) ;
f or ( i nt i =0; i <l i st a. si ze( ) ; i ++) {%>
<%=l i st a. get ( i ) . t oSt r i ng( ) %>
<br / >
<%}%>
</ h2>
</ cent er >
</ body>
</ ht ml >
detalles.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<%Ar r ayLi st <Ll amadaBean> l l amadas=( Ar r ayLi st ) r equest .
get At t r i but e( " l l amadas" ) ; %>
<h1>Li st ado de Ll amadas</ h1> <br / >
<t abl e bor der =" 1" wi dt h=" 60%" >
<t h>Tel f ono del usuar i o</ t d>
<t h>Tel f ono dest i no</ t h>
<t h>Dur aci n ( segundos) </ t h>
<t h>Tar i f a</ t h>
<t h>Cost e</ t h>
<t h>Fecha</ t h>
<%f or ( i nt i =0; i <l l amadas. si ze( ) ; i ++) {
Ll amadaBean l l amada=l l amadas. get ( i ) ; %>
<t r >
<t d><%=l l amada. get Tel ef ono( ) %></ t d>
124 STRUTS RA-MA

<t d><%=l l amada. get Dest i no( ) %></ t d>
<t d><%=l l amada. get Dur aci on( ) %></ t d>
<t d><%=l l amada. get Tar i f a( ) %></ t d>
<t d><%=l l amada. get Cost e( ) %></ t d>
<t d><%=l l amada. get Fecha( ) %></ t d>
</ t r >
<%}%>
</ t abl e>
<br / >
</ cent er >
</ body>
</ ht ml >
factura.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>


<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<br / ><br / >
<%Val i daci onFor musuar i o=( Val i daci onFor m) sessi on.
get At t r i but e( " Val i daci onFor m" ) ; %>
<h2>El usuar i o <%=usuar i o. get Usuar i o( ) %> ha gast ado
<b><%=r equest . get At t r i but e( " pr eci o" ) %></ b>
eur os en l l amadas
</ h2>
</ cent er >
</ body>
</ ht ml >
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 125

4.2.4 Clase ActionForm
Como vimos en el Captulo anterior la clase ActionForm facilita la
creacin de JavaBeans para la gestin de los datos de usuario procedentes de un
formulario XHTML.
Basta con crear una subclase de ActionForm en la que se incluyan los
miembros y mtodos set/get y asociar la misma con el objeto Action
correspondiente, para que las clases ActionServlet y RequestProcessor se
encarguen automticamente de todo el proceso de instanciacin, recuperacin y
rellenado del objeto.
4.2.4.1 CICLO DE VIDA DE UN ACTIONFORM
La mejor manera de comprender el tratamiento que realiza Struts con este
objeto es analizar su ciclo de vida. En la figura 26 tenemos un diagrama en el que
se aprecian los estados por los que puede pasar un ActionForm durante el
procesamiento de una peticin en el Controlador.





Fig. 26. Ciclo de vida de un ActionForm
Pasemos a continuacin a describir estos estados:
Creacin. Cuando llega al Controlador una peticin desde el
cliente para la que se determina que debe ser utilizado un
determinado ActionForm que almacene los datos de usuario, se
comprueba la existencia de una instancia previa de la clase en el
mbito definido mediante el atributo scope del elemento <action>.
En caso de no encontrarla, el Controlador proceder a la creacin
de una nueva instancia y a su almacenamiento en el mbito
especificado.
creacin
recuperacin
limpieza rellenado validacin
reset()
reset()
setXxx() validate()
126 STRUTS RA-MA

Como ya se indic al principio del Captulo durante el anlisis del
procesamiento de una peticin, este proceso es realizado por el
mtodo processActionForm() del objeto RequestProcessor.
Recuperacin. Retomando el proceso descrito anteriormente, si se
encuentra una instancia de ActionForm asociada al tipo de peticin
en curso, el Controlador obtiene una referencia a dicha instancia
para su reutilizacin.
Limpieza. Una vez que el Controlador dispone de la referencia al
objeto ActionForm (nuevo o ya existente), procede a invocar al
mtodo reset() del mismo. El programador puede sobrescribir este
mtodo e incluir algn tipo de operacin de limpieza o
inicializacin de los datos miembro del bean, a fin de que la
existencia de datos previos (algo que puede suceder al reutilizar
instancias ya existentes) no desvirte el nuevo estado de la
instancia.
Rellenado. Tras el reseteo de la instancia el Controlador procede a
rellenar los datos miembro de la misma con el contenido del
formulario enviado en la peticin. Para llevar a cabo esta operacin
el Controlador realiza de forma automtica las conversiones de
datos necesarias y posteriormente invoca a los mtodos setXxx()
asociados con cada dato.
Validacin. Antes de pasar la peticin al objeto Action encargado
de su procesamiento se procede a la validacin de los datos
introducidos en el bean, para lo cual el Controlador, desde el
mtodo processValidate() del objeto RequestProcessor, realiza una
llamada al mtodo validate() de ActionForm. Ser responsabilidad
del programador sobrescribir este mtodo e incluir en l las
instrucciones encargadas de validar los datos, segn los criterios
establecidos por la propia lgica de la aplicacin. El formato del
mtodo validate() es el que se muestra a continuacin:
public ActionErrors() validate()
La llamada al mtodo validate() devolver al Controlador un
objeto ActionErrors con los errores detectados durante el proceso
de validacin. Si el valor devuelto por el mtodo es distinto de
null, entonces el Controlador cancelar el procesamiento de la
peticin y en vez de invocar al mtodo execute() del objeto Action
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 127

asociado a la misma, redirigir al usuario a la pgina indicada en el
atributo input del elemento <action>, que normalmente suele ser la
misma pgina desde la que se lanz la peticin.
Por ejemplo, dada la siguiente definicin del elemento <action>:
<action name= LoginForm
:
input=/login.jsp/>
En caso de que el mtodo validate() del objeto LoginForm
devuelva un valor distinto de null al ser invocado, el usuario ser
redirigido a la pgina login.jsp.
Se puede impedir la llamada al mtodo validate() del objeto
ActionForm para una determinada accin, especificando el valor
false en el atributo validate del elemento <action>correspondiente.
De manera predeterminada la validacin de objetos ActionForm se
encuentra habilitada.
La siguiente implementacin de ejemplo del mtodo validate()
generara un error en caso de que la longitud del campo password
del bean fuera inferior a 8 caracteres:
:
publ i c Act i onEr r or s val i dat e( ) {
Act i onEr r or s er r or es=nul l ;
i f ( t hi s. passwor d. l engt h( ) <8) {
er r or es=new Act i onEr r or s( ) ;
er r or es. add( new Act i onMessage( " er r or " ,
" er r or . passwor d. l owl engt h" ) ) ;
}
r et ur n er r or es;
}
:
Para poder mostrar los mensajes de los errores generados por
validate() en la pgina a la que ha sido redirigido el usuario,
utilizaremos el tag <html:errors/>. Este elemento recorre todos los
objetos de error registrados en ActionErrors y, para cada uno de
128 STRUTS RA-MA

ellos, muestra una lnea con el mensaje de error asociado en el
lugar de la pgina donde se encuentra el elemento.
4.2.5 ActionErrors y ActionMessage
Tal y como se acaba de indicar en el punto anterior, la clase ActionErrors
encapsula los mensajes de error generados en el interior del mtodo validate() de
un ActionForm. Cada error est descrito a su vez mediante un objeto
ActionMessage, el cual encapsula la clave del mensaje de error asociado. Los
mensajes de error con sus claves correspondientes se registran en el archivo
ApplicationResource.properties.
Para aadir un error a la coleccin ActionErrors se utilizar el mtodo
add() de esta clase, pasando como argumento en la llamada un nombre de
propiedad asociada al error y el objeto ActionMessage que lo describe:
public void add(String property, ActionMessage mensaje)
El nombre de la propiedad puede ser utilizado como valor del atributo
property del tag <html:errors/>en caso de que se quiera mostrar nicamente el
mensaje asociado a esa propiedad. En el ejemplo de mtodo validate() presentado
en el punto anterior se crea un objeto ActionErrors formado por un nico error,
error cuyo mensaje asociado se encuentra registrado en el archivo
ApplicationResource.properties con la clave error.password.lowlength.
PRCTICA 4.3. CONTROL DE DATOS DE REGISTRO
Descripcin
En esta prctica implementaremos el cdigo necesario para realizar la
verificacin de los datos de la pgina de registro de usuarios utilizada en prcticas
anteriores (figura 27), antes de que stos sean procesados por la aplicacin.
Los criterios para considerar vlidos los datos sern los siguientes:
Los campos usuario y password sern obligatorios.
El password introducido en segundo lugar debe coincidir con el
primero.
La direccin de correo electrnico deber contar con el carcter @.
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 129









Fig. 27. Pgina de registro de usuarios
En caso de incumplirse alguno de los criterios de validacin anteriores el
usuario ser mantenido en la propia pgina de registro, indicndole mediante algn
mensaje descriptivo el motivo del error.
Desarrollo
Los anteriores criterios de validacin sern codificados dentro del mtodo
validate() de la clase RegistroForm, creando un objeto ActionMessage por cada
criterio incumplido.
En cuanto a los mensajes de error, sern registrados en el archivo de
recursos con sus correspondientes claves. Utilizando un elemento <html:errors/>
por cada tipo de error mostraremos el mensaje correspondiente al lado de cada
control.

Listado
A continuacin mostraremos nicamente el contenido de los componentes
involucrados en este proceso de validacin.
ApplicationResource.properties
Los mensajes de error con sus correspondientes claves sern:
er r or . usuar i o=El campo usuar i o no puede est ar vac o
130 STRUTS RA-MA

er r or . passwor d=El campo passwor d no puede est ar vac o
er r or . emai l =Debe i nt r oduci r una di r ecci n de cor r eo vl i da
er r or . passwor d. nomat ch=El passwor d i nt r oduci do en segundo
l ugar no coi nci de con el pr i mer o
RegistroForm.java
package j avabeans;
i mpor t j avax. ser vl et . ht t p. Ht t pSer vl et Request ;
i mpor t or g. apache. st r ut s. act i on. *;

publ i c cl ass Regi st r oFor mext ends
or g. apache. st r ut s. act i on. Act i onFor m{
pr i vat e St r i ng nombr e;
pr i vat e St r i ng apel l i dos;
pr i vat e St r i ng usuar i o;
pr i vat e St r i ng passwor d;
pr i vat e St r i ng passwor dr ep;
pr i vat e St r i ng emai l ;

publ i c St r i ng get Nombr e( ) {
r et ur n nombr e;
}
publ i c voi d set Nombr e( St r i ng nombr e) {
t hi s. nombr e = nombr e;
}
publ i c St r i ng get Apel l i dos( ) {
r et ur n apel l i dos;
}
publ i c voi d set Apel l i dos( St r i ng apel l i dos) {
t hi s. apel l i dos = apel l i dos;
}
publ i c St r i ng get Usuar i o( ) {
r et ur n usuar i o;
}
publ i c voi d set Usuar i o( St r i ng usuar i o) {
t hi s. usuar i o = usuar i o;
}
publ i c St r i ng get Passwor d( ) {
r et ur n passwor d;
}
publ i c voi d set Passwor d( St r i ng passwor d) {
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 131

t hi s. passwor d = passwor d;
}
publ i c St r i ng get Passwor dr ep( ) {
r et ur n passwor dr ep;
}
publ i c voi d set Passwor dr ep( St r i ng passwor dr ep) {
t hi s. passwor dr ep = passwor dr ep;
}
publ i c St r i ng get Emai l ( ) {
r et ur n emai l ;
}
publ i c voi d set Emai l ( St r i ng emai l ) {
t hi s. emai l = emai l ;
}
publ i c Act i onEr r or s val i dat e( Act i onMappi ng mappi ng,
Ht t pSer vl et Request r eq) {
Act i onEr r or s er r or s=new Act i onEr r or s( ) ;
//comprueba si se ha suministrado un valor para
//el campo usuario
i f ( usuar i o==nul l | | usuar i o. equal s( " " ) ) {
er r or s. add( " usuar i o" ,
new Act i onMessage( " er r or . usuar i o" ) ) ;
}
/ / compr ueba si se ha sumi ni st r ado un val or par a
/ / el campo passwor d
i f ( passwor d==nul l | | passwor d. equal s( " " ) ) {
er r or s. add( " passwor d" ,
new Act i onMessage( " er r or . passwor d" ) ) ;
}
/ / compr ueba si el passwor d i nt r oduci do en segundo
/ / l ugar coi nci de con el pr i mer o
i f ( ! passwor d. equal s( passwor dr ep) ) {
er r or s. add( " passwor dnomat ch" ,
new Act i onMessage( " er r or . passwor d. nomat ch" ) ) ;
}
/ / compr ueba si l a di r ecci n de emai l es vl i da
i f ( emai l . i ndexOf ( " @" ) ==- 1) {
er r or s. add( " emai l " ,
new Act i onMessage( " er r or . emai l " ) ) ;
}
r et ur n er r or s;
132 STRUTS RA-MA

}
}
registro.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- l ogi c
pr ef i x=" l ogi c" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<body>
<cent er >
<h1>Regi st r o de usuar i os</ h1>
<ht ml : f or mact i on=" / r egi st r ar " met hod=" POST" >
<t abl e>
<t r >
<t d>Nombr e: </ t d>
<t d><ht ml : t ext pr oper t y=" nombr e" / ></ t d>
<t d>&nbsp; </ t d>
</ t r >
<t r >
<t d>Apel l i dos: </ t d>
<t d ><ht ml : t ext pr oper t y=" apel l i dos" / ></ t d>
<t d>&nbsp; </ t d>
</ t r >
<t r >
<t d>Usuar i o: </ t d>
<t d><ht ml : t ext pr oper t y=" usuar i o" / ></ t d>
<t d><ht ml : er r or s pr oper t y=" usuar i o" / ></ t d>
</ t r >
<t r >
<t d>Passwor d: </ t d>
<t d><ht ml : passwor d pr oper t y=" passwor d" / ></ t d>
<t d><ht ml : er r or s pr oper t y=" passwor d" / ></ t d>
</ t r >
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 133

<t r >
<t d>Repet i r Passwor d: </ t d>
<t d><ht ml : passwor d pr oper t y=" passwor dr ep" / ></ t d>
<t d><ht ml : er r or s pr oper t y=" passwor dnomat ch" / ></ t d>
</ t r >
<t r >
<t d>Emai l : </ t d>
<t d><ht ml : t ext pr oper t y=" emai l " / ></ t d>
<t d><ht ml : er r or s pr oper t y=" emai l " / ></ t d>
</ t r >
<t r >
<t d col span=" 3" >
<br / >
<ht ml : submi t pr oper t y=" submi t " val ue=" Regi st r ar " / >
&nbsp; &nbsp;
<ht ml : r eset val ue =" Li mpi ar " / >
</ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
<br / >
</ cent er >
</ body>
</ ht ml : ht ml >
4.3 CONTROL DE EXCEPCIONES EN STRUTS
Una vez validados los datos de usuario, stos podrn ser utilizados por las
clases de accin para su procesamiento. Durante este proceso pueden producirse
excepciones que el desarrollador debe ser capaz de gestionar.
En Struts las excepciones dentro de una clase de accin pueden ser
capturadas de dos maneras:
Utilizando bloques try-catch. Constituye la manera tradicional de
capturar excepciones en aplicaciones J ava, incluyendo la gestin
de las mismas dentro del propio cdigo de la aplicacin.
Mediante un control declarativo de excepciones. En este caso la
captura de excepciones se realiza mediante unas etiquetas XML
especiales que se aaden al archivo de configuracin struts-
134 STRUTS RA-MA

config.xml. Ser este mecanismo de control el que analicemos en
este apartado.
4.3.1 Gestin declarativa de excepciones
A fin de evitar el uso de incmodos bloques try-catch para capturar y
gestionar las excepciones dentro del propio cdigo de la aplicacin, Struts
proporciona un elemento llamado <exception>que permite realizar esta captura de
las excepciones desde el archivo de configuracin de la aplicacin.
Hay que recalcar que este tipo de control slo puede ser aplicado con
aquellas excepciones que se producen en las subclases Action de la aplicacin,
pero no en el Modelo o en las clases ActionForm.
El elemento <exception>puede ser incluido en dos lugares diferentes del
archivo struts-config.xml:
Dentro del elemento <global-exceptions>. En este caso la
excepcin se controla a nivel global, es decir, para todos los Action
de la aplicacin en donde sta se pueda producir. Para cada tipo de
excepcin que se quiera capturar se utilizar un elemento
<exception>diferente:
<struts-config>
<global-exceptions>
<exception .../>
<exception.../>
</global-exceptions>
:
</struts-config>
Dentro de un elemento <action>. En este caso la excepcin ser
capturada nicamente si se produce en el interior de la clase Action
a la que hace referencia el elemento. En el siguiente ejemplo la
captura de la excepcin slo se realizara en la clase
misacciones.EjemploAction:
<action-mappings>
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 135

<action type="misacciones.EjemploAction" ....>
<exception.../>
</action>
:
</action-mappings>
4.3.2 Implementacin de la gestin declarativa de excepciones
Cuando dentro de un objeto Action se produce una excepcin que ha sido
declarada mediante el elemento <exception>, bien como una excepcin global o
bien como una excepcin asociada a esa accin, Struts genera un objeto
ActionErrors con el ActionMessage asociado a la excepcin y transfiere el control
de la aplicacin al recurso indicado en el propio elemento <exception>.
Todo este proceso se controla a travs de los atributos del elemento
<exception>, cuyos valores determinan los distintos parmetros relativos a la
gestin de la excepcin. Estos atributos son:
type. Nombre de la clase de excepcin que se va a capturar.
key. Nombre de la clave definida en el archivo de recursos
ApplicationResource.properties asociada al mensaje de error. Esta
clave ser utilizada para construir el objeto ActionMessage.
path. URL relativa a la pgina J SP donde ser trasferido el usuario
en caso de que se produzca la excepcin. En el interior de esta
pgina podremos hacer uso del elemento <html:errors/> para
acceder al mensaje de error asociado a la excepcin.
handler. En vez de redirigir al usuario a una pgina de la
aplicacin podemos optar por realizar un control ms exhaustivo
de la excepcin. En este caso tendremos que crear una clase
especial para el tratamiento de la excepcin, clase que deber ser
referenciada en este atributo a fin de que Struts pueda crear un
objeto de la misma y transferirla el control del programa cuando se
produzca la excepcin. Ms adelante analizaremos con detalle este
proceso.
136 STRUTS RA-MA

Para comprender el funcionamiento del control declarativo de excepciones
vamos a incluir un control de este tipo en la aplicacin que desarrollamos en la
prctica 3.1 relativa a la informacin sobre llamadas realizadas.
Lo que haremos ser controlar una excepcin personalizada que se
producir desde la propia aplicacin en caso de que el usuario validado no
disponga de telfonos asociados, redirigindole a una pgina llamada
sintelefonos.jsp donde se le informar de esta situacin.
Lo primero ser definir la clase de excepcin, a la que llamaremos
SinTelefonosException y cuyo cdigo ser tan simple como el que se indica en
el siguiente listado:
package excepci ones;
publ i c cl ass Si nTel ef onosExcept i on ext ends Except i on{
}
Como vemos esta clase hereda toda la funcionalidad que necesitamos de
Exception, no siendo necesario sobrescribir o aadir mtodo alguno.
Por otro lado, tendremos que modificar la clase ValidarAction para que en
caso de que el usuario no disponga de telfonos asociados se lance la excepcin.
He aqu el cdigo de esta clase, indicndose las modificaciones realizadas en fondo
sombreado:
package ser vl et s;

i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t model o. *;
i mpor t j avabeans. *;
publ i c cl ass Val i dar Act i on ext ends Act i on {
publ i c Act i onFor war d execut e( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Si nTel ef onosExcept i on {
//obtiene los datos del driver y de la cadena de
//conexin de los parmetros de contexto
//definidos en Web.xml
St r i ng dr i ver =t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " dr i ver " ) ;
RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 137

St r i ng cadenaCon=t hi s. get Ser vl et ( ) .
get Ser vl et Cont ext ( ) . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=
new Gest i onCl i ent es( dr i ver , cadenaCon) ;
Val i daci onFor mvf =( Val i daci onFor m) f or m;
i f ( gc. val i dar ( vf ) ) {
Gest i onTel ef onos gt =
new Gest i onTel ef onos( dr i ver , cadenaCon) ;
//si no dispone de telfonos
//se lanza la excepcin
i f ( gt . get Tel ef onos( vf . get Passwor d( ) ) . si ze( ) ==0) {
t hr ow new Si nTel ef onosExcept i on( ) ;
}
vf . set Tel ef onos(
gt . get Tel ef onos( vf . get Passwor d( ) ) ) ;
r et ur n mappi ng. f i ndFor war d( " bi enveni da" ) ;
}
el se{
vf . set Mensaj e( " <h2>Combi naci n de usuar i o
y passwor d i ncor r ect a! </ h2>" ) ;
r et ur n mappi ng. f i ndFor war d( " er r or " ) ;
}
}
}
Seguidamente, aadiremos en el archivo ApplicationResource.properties el
mensaje de error que queremos mostrar al usuario con su clave asociada:
error.sintelefonos=El usuario no tiene telfonos registrados!!
A continuacin, crearemos la pgina J SP a la que redireccionaremos al
usuario a la que, como ya hemos indicado, llamaremos sintelefonos.jsp. El
cdigo ser muy sencillo, tan slo mostrar el mensaje de error al usuario:
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
138 STRUTS RA-MA


<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>Pgi na de er r or </ t i t l e>
</ head>
<body>
<h1>
<ht ml : er r or s/ >
</ h1>
</ body>
</ ht ml >
Por ltimo, registraremos el elemento <exception>con los datos para la
captura de la excepcin. Este elemento lo incluiremos dentro del elemento
<action>asociado a ValidarAction:
<act i on i nput =" / " name=" Val i daci onFor m" pat h=" / val i dar "
scope=" r equest " t ype=" ser vl et s. Val i dar Act i on" >
<f or war d name=" bi enveni da" pat h=" / opci ones. j sp" / >
<f or war d name=" er r or " pat h=" / l ogi n. j sp" / >
<exception type=
"excepciones.SinTelefonosException"
key="error.sintelefonos"
path="/errores.jsp"/>
</ act i on>
Ser necesario adems incluir en el archivo de configuracin la
localizacin de ApplicationResource, para ello se utilizar el elemento <message-
resources>:
<message- r esour ces
par amet er =" com. myapp. st r ut s. Appl i cat i onResour ce" / >



RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 139

4.3.3 Clases personalizadas para la gestin de excepciones
Si lo que queremos es realizar una gestin ms elaborada de la excepcin
en vez de una simple redireccin a una determinada pgina de la aplicacin,
debemos crear una clase especial para el tratamiento de la excepcin e incluir en
ella todas las instrucciones que queramos ejecutar en caso de que sta llegue a
producirse.
Esta clase deber heredar org.apache.struts.action.ExceptionHandler, la
cual proporciona un mtodo execute() que ser sobrescrito por el programador y en
el que incluir todas las instrucciones necesarias para el tratamiento de la
excepcin.
El mtodo execute() de ExceptionHandler es muy similar al execute() de
Action, declarando, adems de los cuatro parmetros de ste, otros dos adicionales
que proporcionan al mtodo informacin relativa a la excepcin:
public ActionForward execute(Exception ex,
ExceptionConfig config,
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException
Estos dos nuevos parmetros son:
ex. Este parmetro contiene al objeto Exception generado en la
excepcin.
config. Se trata de un objeto ExceptionConfig en el que se
encapsula toda la informacin almacenada en el elemento
<exception>asociado a la excepcin.
Una vez implementada la clase para el tratamiento de la excepcin, habr
que registrarla en el elemento <exception>con el que se va a capturar la excepcin
dentro de su atributo handler. De esta forma, en el momento en que se produzca la
140 STRUTS RA-MA

excepcin se crear un objeto de la subclase de ExceptionHandler y se pasar el
control al mismo invocando a su mtodo execute().
Como podemos comprobar, este mtodo tambin debe devolver un objeto
ActionForward asociado a la vista a la que tendr que ser redirigido el usuario
despus de tratar la excepcin.
Supongamos que en el caso del ejemplo anterior, en vez de mandar al
usuario a la pgina sintelefonos.jsp al producirse la excepcin, quisiramos por
ejemplo almacenar el password del usuario en una variable de sesin y redirigirle
despus a una nueva pgina de alta de telfonos llamada telefonos.jsp, cuya
direccin virtual asociada en struts-config.xml es alta.
La clase para la gestin de la excepcin que tendramos que implementar
en esta situacin podra ser:
package excepci ones;
publ i c cl ass Gest i on ext ends Except i onHandl er {
publ i c Act i onFor war d execut e( Except i on ex,
Except i onConf i g conf i g,
Act i onMappi ng mappi ng,
Act i onFor mf or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Ser vl et Except i on{
Ht t pSessi on s=r equest . get Sessi on( ) ;
//recuperacin del bean que almacena
//los credenciales del usuario
Val i daci onFor mvf =( Val i daci onFor m) r equest .
get At t r i but e( " Val i daci onFor m" ) ;
/ / al macenami ent o del passwor d en l a var i abl e
/ / de sesi n
s. set At t r i but e( " pwd" , vf . get Passwor d( ) ) ;
r et ur n mappi ng. f i ndFor war d( " al t a" ) ;
}
}
En cuanto al registro de la excepcin en el elemento <action>, quedara
como se indica a continuacin:

RA-MA CAPTULO 4. ANLISIS DEL API DE STRUTS 141

<act i on i nput =" / " name=" Val i daci onFor m"
pat h=" / val i dar "
scope=" r equest "
t ype=" ser vl et s. Val i dar Act i on" >

<f or war d name=" bi enveni da"
pat h=" / opci ones. j sp" / >
<f or war d name=" er r or "
pat h=" / l ogi n. j sp" / >
<exception type=
"excepciones.SinTelefonosException"
key="error.sintelefonos"
handler="excepciones.Gestion"/>
</ act i on>
Como podemos observar en la definicin del elemento <exception>
anterior, la utilizacin del atributo handler para la especificacin de la clase que
realizar la gestin de la excepcin hace que no sea necesario utilizar el atributo
path.
Por otro lado, aunque no se haga uso de la pgina de error, el mensaje de
error asociado al objeto ActionMessage generado en la excepcin podr ser
utilizado tambin en la pgina a la que ser redirigido el usuario desde la clase
manejadora (la que tiene como direccin virtual asociada alta).





5Captulo 5
LIBRERAS DE ACCIONES JSP DE STRUTS
Los tags J SP que Struts pone a disposicin del programador a travs de las
libreras de acciones incluidas en el framework permiten implementar la mayor
parte de la funcionalidad de las pginas J SP que forman la vista de una manera
rpida y sencilla y sin apenas tener que utilizar scriptlets de cdigo Java.
Durante el Captulo 4 tuvimos la oportunidad de analizar el funcionamiento
de la librera html que, entre otras, incluye acciones que facilitan el volcado de
datos en un JavaBean, suministrados a travs de un formulario XHTML.
A lo largo de este Captulo analizaremos las libreras bean o logic, de
manera que al finalizar el mismo seremos capaces de crear pginas J SP totalmente
funcionales sin utilizar scriptlets de cdigo J ava de servidor. Otra de las libreras de
acciones importantes de Struts, tiles, ser estudiada durante el Captulo dedicado a
la creacin de plantillas.
Tanto el cdigo de estas acciones como los archivos de librera .tld se
encuentran en el archivo struts-taglib-1.3.9.jar suministrado con el pack de
distribucin de Struts y, como ya indicamos en el Captulo 3, debera estar incluido
en el directorio WEB-INF\lib de nuestra aplicacin.
5.1 LIBRERA BEAN
La librera bean proporciona acciones para manipular objetos en una
aplicacin, objetos que pueden ser de diferente naturaleza y ofrecer distinta
funcionalidad.
144 STRUTS RA-MA

Para poder hacer uso de sus acciones en una pgina J SP, habr que incluir
mediante la directiva taglib la siguiente referencia a la librera struts-bean.tld:
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
Analizaremos a continuacin las acciones ms importantes de esta librera.
5.1.1 write
Esta accin la utilizamos en el primer ejemplo de aplicacin Struts que se
desarroll en el Captulo 3 y tiene como funcin incluir en la pgina de respuesta la
informacin almacenada en un determinado objeto. Sus principales atributos son:
name. Nombre o identificador del objeto que contiene la
informacin.
scope. mbito en el que se encuentra el objeto. Si no se indica
ningn valor para este atributo se intentar localizar el objeto en
todos los mbitos siguiendo el orden: page, request, session y
application.
property. Propiedad del objeto cuyo valor se quiere incluir en la
pgina. Si no se utiliza este atributo se recuperar el resultado de
invocar al mtodo toString() sobre el objeto.
format. Cadena de caracteres que define el formato de
presentacin que se va a aplicar sobre el dato. Por ejemplo, la
cadena 0.00 indica que el valor debe mostrarse como una
cantidad numrica con dos cifras decimales. Si no se especifica
este atributo se utilizar el formato por defecto para el tipo de dato.
filter. Se trata de un atributo de tipo boolean. Si su valor es true se
aplicar un filtro para los caracteres especiales incluidos en el dato,
a fin de que no sean interpretados como texto XHTML por el
navegador. Por ejemplo, si dentro de la cadena de texto de
presentacin se incluye el carcter <, ste ser sustituido por su
correspondiente referencia &lt;.
Mediante la siguiente accin de ejemplo se mostrara en la pgina de
respuesta, dentro de un elemento <h1>, el contenido de la propiedad titulo de un
bean de sesin llamado libro:

RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 145

<h1><bean: wr i t e name=" l i br o" pr oper t y=" t i t ul o"
scope=" sessi on" / ></ h1>
La accin anterior equivale al siguiente scriptlet de J ava:
<%Li br o l i br o;
l i br o = ( Li br o) sessi on. get At t r i but e( " l i br o" ) ; %>
<h1><%=l i br o. get Ti t ul o( ) %></ h1>
5.1.2 parameter
Recupera el valor de un parmetro enviado en la peticin y lo almacena en
una variable J SP. Esta variable tendr mbito de pgina y podr ser referenciada
desde otras acciones de la misma pgina J SP.
Entre sus atributos destacamos:
id. Nombre o identificador asignado a la variable.
name. Nombre del parmetro cuyo valor se quiere almacenar en la
variable.
value. En caso de que no se haya enviado en la peticin ningn
parmetro con el nombre indicado en name, se asignar a la
variable el valor definido en este atributo.
El siguiente ejemplo recupera el valor del parmetro password y lo
muestra ms adelante en la misma pgina:
<bean: par amet er i d=" pwd" name=" passwor d" / >
:
<p>El passwor d envi ado val e:
<b><bean: wr i t e name=" pwd" / ></ b>
</ p>
Como se puede observar en este ejemplo, dado que lo que contiene una
variable J SP es una referencia a un objeto, podemos utilizar tambin la accin write
para acceder a este tipo de variables.
5.1.3 cookie
Recupera el valor de una cookie enviada en la peticin y lo almacena en
una variable J SP.
146 STRUTS RA-MA

Los principales atributos de la accin son:
id. Nombre o identificador asignado a la variable.
name. Nombre de la cookie cuyo valor se quiere almacenar en la
variable.
value. En caso de que no se haya enviado en la peticin ninguna
cookie con el nombre indicado en name, se asignar a la variable el
valor indicado en este atributo.
El siguiente ejemplo muestra en la pgina el contenido de la cookie
usuario, mostrndose el valor sin datos en caso de que sta no exista:
<bean: cooki e i d=" user " name=" usuar i o" / >
:
<p>Le doy l a bi enveni da a mi pgi na sr . / a:
<b><bean: wr i t e name=" user " / ></ b>
</ p>
5.1.4 header
Recupera el valor de un encabezado enviado en la peticin y lo almacena
en una variable J SP.
Al igual que en las dos acciones anteriores los principales atributos de
header son:
id. Nombre o identificador asignado a la variable.
name. Nombre del encabezado cuyo valor se quiere almacenar en
la variable.
value. En caso de que no se haya enviado en la peticin ningn
encabezado con el nombre indicado en name, se asignar a la
variable el valor definido en este atributo.
5.1.5 message
Permite mostrar en la pgina un mensaje de texto almacenado en un
archivo externo, concretamente en ApplicationResource.properties. Este tag es
muy utilizado en internacionalizacin de aplicaciones, permitiendo que los textos
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 147

especficos de cada idioma puedan residir en archivos de recursos externos en vez
de ser introducidos directamente en la pgina.
Los principales atributos de esta accin son:
key. Clave asociada en ApplicationResource.properties a la cadena
de caracteres. Struts localizar en el archivo de recursos el texto
que tenga la clave especificada en este atributo y lo mostrar en la
pgina.
name. En vez de suministrar directamente en key el valor de la
clave se puede extraer sta de un objeto, en cuyo caso el nombre o
identificador del objeto se indicar en este atributo.
property. Nombre de la propiedad del objeto indicado en name
que contiene la clave del mensaje.
scope. mbito del objeto especificado en name.
Suponiendo que tenemos registrada la siguiente entrada en el archivo de
recursos:
struts.message=Struts is easy
el bloque de acciones que se muestra a continuacin almacena el nombre de la
clave anterior en la propiedad clave de un objeto de la clase javabeans.Datos,
mostrando a continuacin el mensaje asociado a dicha clave:
<j sp: useBean i d=" i nf o" cl ass=" j avabeans. Dat os" >
<j sp: set Pr oper t y name=" i nf o" pr oper t y=" cl ave"
val ue=" wel come. message" / >
</ j sp: useBean>
<b>Mensaj e</ b>:
<h2>
<bean: message name=" i nf o" pr oper t y=" cl ave" / >
</ h2>
5.1.6 define
Esta accin almacena en una variable J SP una referencia a un objeto
existente en la aplicacin o, en su defecto, un nuevo objeto String creado por la
propia accin a partir de una determinada cadena de texto.
148 STRUTS RA-MA

Entre los atributos ms significativos proporcionados por la accin
tenemos:
id. Nombre o identificador asignado a la variable J SP.
name. Nombre del objeto existente en cualquiera de los mbitos de
aplicacin cuya referencia ser almacenada en la variable.
property. Si se especifica este atributo en la accin, en vez de
asignar a la variable J SP la referencia al objeto indicado en name
se almacenar en sta el valor de la propiedad del objeto cuyo
nombre se especifica en este atributo. Por ejemplo, si el valor del
atributo name es mipersona y el de property es apellido, en la
variable J SP indicada en id se almacenar una referencia al objeto
devuelto (String en este caso) por la llamada a getApellido() sobre
el bean mipersona.
scope. mbito donde se debe localizar al objeto especificado en
name. Si no se emplea este atributo el objeto ser buscado en todos
los mbitos de la aplicacin siguiendo el orden: page, request,
session y application.
toScope. Indica el mbito en el que se almacenar la referencia
asignada a la variable J SP. Si no se especifica este atributo la
variable J SP tendr mbito de pgina.
Para entender mejor el funcionamiento de la accin define vamos a pensar
en el siguiente ejemplo: supongamos que tenemos una clase de tipo J avaBean
llamada Datos que encapsula una cadena de caracteres dentro de la propiedad
valor. Desde una pgina inicio.jsp creamos una instancia de la misma y
redireccionamos al usuario a otra pgina llamada pagina1.jsp, tal y como se indica
a continuacin:
<j sp: useBean i d=" obj " cl ass=" j avabeans. Dat os"
scope=" sessi on" / >
<j sp: set Pr oper t y name=" obj " pr oper t y=" val or "
val ue=" cadena de pr ueba Dat os" / >
<%r esponse. sendRedi r ect ( " pagi na1. j sp" ) ; %>
Por su parte, pagina1.jsp utilizar la accin define para almacenar en una
variable J SP el objeto obj con mbito request para despus pasar la peticin a
pagina2.jsp:
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 149

<bean: def i ne i d=" mi var " name=" obj "
scope=" sessi on" t oScope=" r equest " / >
<j sp: f or war d page=" pagi na2. j sp" / >
En cuanto a pagina2.jsp, utilizar el elemento write para mostrar en la
pgina de respuesta el contenido de la propiedad valor del objeto, utilizando la
variable J SP creada en pagina1.jsp:
<bean: wr i t e name=" mi var " scope=" r equest " pr oper t y=" val or " / >
De esta manera, al solicitar la pgina inicio.jsp desde su navegador el
usuario recibir una pgina de respuesta en la que le aparecer el mensaje:
cadena de prueba Datos
5.1.7 page
Almacena en una variable J SP a uno de los objetos implcitos de J SP a fin
de que puedan ser referenciados posteriormente desde alguna otra accin de la
librera bean, como por ejemplo write.
Los atributos disponibles para esta accin son:
id. Nombre de la variable J SP en la que se almacenar la referencia
al objeto.
property. Nombre del objeto implcito J SP (page, request,
response, session, application o config).
5.1.8 size
Almacena en una variable J SP el nmero de elementos de un array o
coleccin. Sus atributos son:
id. Nombre o identificador de la variable J SP.
name. Nombre del objeto en el que se encuentra la coleccin.
property. Propiedad del objeto especificado en name que contiene
la coleccin cuyo tamao se almacenar en la variable. Si no se
indica ningn valor para este atributo se considerar al propio
objeto indicado en name como el objeto de coleccin.
150 STRUTS RA-MA

scope. mbito en el que se encuentra el objeto indicado en name.
Si no se utiliza este atributo se buscar el objeto en todos los
mbitos de la aplicacin, siguiendo el mismo criterio indicado en
acciones anteriores.
collection. Como alternativa a los atributos anteriores se puede
indicar directamente en este atributo, mediante una expresin J SP,
el objeto de coleccin o array cuyo tamao debe ser almacenado en
la variable J SP.
El siguiente ejemplo nos muestra el nmero de autores de un libro. El
objeto libro se encuentra almacenado en una variable de sesin y una de sus
propiedades, autores, contiene la coleccin con los nombres de los autores del
mismo:
<bean: si ze i d=" t ot al aut or es" name=" l i br o"
scope=" sessi on" pr oper t y=" aut or es" / >
El nmer o de aut or es del l i br o es:
<bean: wr i t e name=" t ot al aut or es" / >
5.2 LIBRERA LOGIC
En la librara logic de Struts encontramos un amplio abanico de acciones
con las que podemos realizar cualquier operacin de control de flujo de ejecucin
en la pgina, como la generacin de resultados diferentes en funcin de una
condicin, la iteracin sobre colecciones de objetos, etc. Todo ello sin necesidad de
escribir una sola lnea de cdigo J ava en la pgina.
Las acciones logic se encuentran registradas en el archivo struts-logic.tld
incluido en la librera struts-core-1.3.9.jar. Para poder utilizar estas acciones
debemos incluir la siguiente referencia taglib en la pgina J SP:
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic"
prefix="logic" %>
Veamos a continuacin las acciones ms importantes que se encuentran en
esta librera.
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 151

5.2.1 equal
Evala el contenido anidado de la accin si el dato especificado en uno de
sus atributos es igual a la constante indicada en su atributo value. La comparacin
puede ser numrica o String, segn la naturaleza de los valores a comparar.
El formato de utilizacin de esta accin sera pues:
<logic:equal ....>
<!--contenido evaluado si se produce la igualdad-->
</logic:equal>
Como ya se ha indicado, el atributo value debe contener el valor con el que
se comparar el dato u objeto indicado en los restantes atributos de la accin, valor
que ser suministrado como un literal numrico o de texto. El uso de este atributo
es obligatorio.
En cuanto al resto de los atributos de la accin stos son:
cookie. Nombre de la cookie enviada en la peticin HTTP cuyo
valor ser comparado con value.
parameter. Nombre del parmetro enviado en la peticin HTTP
cuyo valor ser comparado con value.
header. Nombre del encabezado de la peticin HTTP cuyo valor
ser comparado con value.
name. Nombre del objeto, existente en alguno de los mbitos de la
aplicacin, con el que ser comparado value.
property. El valor de este atributo representa el nombre de la
propiedad del bean indicado en name, cuyo valor ser comparado
con value.
scope. mbito del objeto especificado en name. Si no se especifica
este atributo el objeto ser buscado en todos los mbitos, siguiendo
el orden: page, request, session y application.
Veamos el siguiente ejemplo:
152 STRUTS RA-MA

Supongamos que tenemos una pgina inicio.jsp desde la que
redireccionamos al usuario a otra pgina llamada pagina1.jsp:
<%r esponse. sendRedi r ect ( " pagi na1. j sp?par =35" ) ; %>
Por otro lado, en pagina1.jsp tenemos el siguiente cdigo:
<body>
<l ogi c: equal par amet er =" par " val ue=" 35" >
<h1>La condi ci n se cumpl e! </ h1>
</ l ogi c: equal >
Pgi na de r esul t ados
</ body>
Si el usuario lanza una solicitud de la pgina inicio.jsp le aparecer en su
navegador una pgina como la que se indica en la figura 28.








Fig. 28. Aspecto de la pgina de respuesta
Los atributos cookie, parameter, header y name no son excluyentes entre
s, pudindose utilizar ms de uno de ellos en una misma accin. En este caso, el
contenido anidado de <logic:equal> slo ser evaluado si la constante
especificada en value coincide con los datos indicados en todos y cada uno de
los atributos anteriores.
Volviendo al ejemplo anterior, supongamos que tenemos adems una clase
de tipo J avaBean llamada Datos con una propiedad numero que almacena valores
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 153

numricos de tipo entero, incluyndose ahora en la pgina inicio.jsp el contenido
que se indica a continuacin:
<j sp: useBean i d=" obj " cl ass=" j avabeans. Dat os"
scope=" sessi on" / >
<j sp: set Pr oper t y name=" obj " pr oper t y=" numer o" val ue=" 10" / >
<%r esponse. sendRedi r ect ( " pagi na1. j sp?par =35" ) ; %>
En cuanto al contenido de pagina1.jsp, incluimos ahora en ella el siguiente
cdigo:
<body>
<l ogi c: equal name=" obj " scope=" sessi on"
pr oper t y=" numer o" par amet er =" par " val ue=" 35" >
<h1>La condi ci n se cumpl e! </ h1>
</ l ogi c: equal >
Pgi na de r esul t ados
</ body>
En este caso se comparar el nmero 35 con el parmetro par y con el
valor de la propiedad numero del objeto de la clase Datos instanciado en la
pgina anterior; como la condicin de igualdad slo se cumple con el parmetro
par (el valor de la propiedad numero del objeto es igual a 10) el cuerpo de la
accin no ser evaluado, mostrndose al usuario la pgina indicada en la figura 29
al lanzar la solicitud de inicio.jsp.







Fig. 29. Pgina de respuesta recibida al solicitar inicio.jsp
154 STRUTS RA-MA

5.2.2 notEqual
Evala el contenido anidado de la accin si el dato especificado en uno de
sus atributos no es igual al valor de la constante indicada en value. Dispone
exactamente de los mismos atributos que equal con idntico significado.
Al igual que sucede con equal, en una misma accin notEqual pueden
aparecer los atributos cookie, parameter, header y name, aunque en este caso
bastar con que el dato especificado en uno de ellos sea diferente a la
constante indicada en value para el cuerpo de la accin sea evaluado.
5.2.3 greaterEqual, lessEqual, greaterThan y lessThan
Se trata de cuatro acciones que tienen la misma estructura y atributos que
las dos anteriores, diferencindose de stas y entre ellas en la condicin para que el
contenido anidado de la accin sea evaluado.
El criterio ser que el dato indicado en los atributos cookie, header,
parameter y name sea mayor o igual que la constante indicada en value para la
accin greaterEqual, menor o igual para lessEqual, mayor para greaterThan y
menor para lessThan.
Si en una misma accin de cualquiera de estas cuatro se emplea ms de un
atributo selector de dato (cookie, parameter, header y name), la condicin se
aplicar sobre cada uno de los datos indicados, evalundose el cuerpo de la
accin si la condicin se cumple en todos ellos.
5.2.4 match
Evala el contenido anidado de la accin si el dato especificado en sus
atributos contiene a la constante indicada en value.
Adems de disponer de los mismos atributos analizados en las acciones
anteriores, match incluye el atributo location, el cual puede tomar los valores
start o end. Si se indica el valor start, la constante especificada en value
deber aparecer al principio del dato para que el contenido de la accin sea
evaluado, mientras que si el valor de location es end la constante deber aparecer
al final del dato. En caso de que no se emplee este atributo, la constante ser
buscada en cualquier parte del dato.
Si tenemos una pgina inicio.jsp con la siguiente instruccin:

RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 155

<%r esponse. sendRedi r ect (
" pr ueba. j sp?par =Pr ueba de at r i but o mat ch en St r ut s" ) ; %>
y en la pgina prueba.jsp incluimos el siguiente cdigo:
<body>
<l ogi c: mat ch par amet er =" par " l ocat i on=" end"
val ue=" mat ch" >
<h1>Val or encont r ado en el par met r o</ h1>
</ l ogi c: mat ch>
Pgi na de r esul t ados
</ body>
el cuerpo de la accin match no ser evaluado, ya que, aunque el valor match se
encuentra incluido en la cadena Prueba de atributo match en Struts enviada como
parmetro, no est situado al final de la misma tal y como se especifica en location.
Si en una misma accin se emplea ms de un atributo selector de dato
(cookie, parameter, header y name) la bsqueda de la constante se llevar a
cabo sobre cada uno de los datos indicados, evalundose el cuerpo de la accin
si la coincidencia se da en alguno de ellos.
5.2.5 noMatch
Dispone de los mismos atributos que match aunque, a diferencia de sta,
evaluar su contenido si el dato no contiene a la constante especificada en value.
En caso de emplear ms de un atributo selector de dato, el contenido ser
evaluado siempre y cuando la constante no est contenida en ninguno de los
datos.
5.2.6 forward
Esta accin transfiere la peticin del usuario a la URL asociada a uno de
los elementos <forward>globales definidos en el archivo de configuracin struts-
config.xml, indicando a travs de su nico atributo name el nombre del elemento
<forward>utilizado.
5.2.7 redirect
Redirecciona al usuario a una determinada URL, pudiendo enviar
diferentes parmetros en la misma. Esta URL puede ser especificada de distintas
156 STRUTS RA-MA

formas segn los atributos utilizados por la accin, ms concretamente, en uno de
los cuatro atributos que se indican a continuacin:
action. Nombre del elemento <action>global que representa el
destino a donde ser redirigido el usuario.
forward. Nombre del elemento <forward>global a cuya URL ser
redireccionado el usuario.
href. Especifica la URL absoluta del destino.
page. URL relativa del destino.
En una determinada accin redirect slo podr definirse uno de los
atributos anteriores.
Por otro lado, en todos los casos se aplicar automticamente la reescritura
en URL para mantener el identificador de sesin en caso de que se desactive el uso
de cookies por el usuario.
Para enviar parmetros en la URL podrn emplearse los siguientes
atributos de la accin:
paramId. Nombre del parmetro que se quiere enviar.
paramName. Nombre del objeto que ser utilizado como valor del
parmetro especificado en paramId.
paramProperty. Propiedad del objeto indicado en paramName
cuyo valor ser enviado como parmetro, en vez del propio objeto.
paramScope. mbito del objeto especificado en paramName. Si
no se utiliza este atributo se intentar localizar el objeto en todos
los mbitos de la aplicacin, siguiendo el orden: page, request,
session y application.
name. Como alternativa a paramId y paramName puede
especificarse en el atributo name un objeto coleccin de tipo
java.util.Map cuyo contenido ser enviado en parmetros de la
URL, siendo la clave de cada elemento el nombre del parmetro y
el propio elemento el valor del mismo.
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 157

property. Si se utiliza este atributo, la coleccin de elementos que
ser enviada en los parmetros de la URL ser obtenida a partir de
la propiedad del objeto especificado en name, cuyo nombre se
indica en este atributo.
Veamos un ejemplo de utilizacin de esta accin: supongamos como en el
ejemplo anterior que tenemos una clase J avaBean llamada Datos con una
propiedad numero que almacena valores numricos enteros. La siguiente pgina
redireccionara al usuario a la URL asociada al elemento <forward>prueba,
pasando como parmetro en la URL el valor de la propiedad numero del objeto
Datos instanciado en la propia pgina:
<body bgcol or =" whi t e" >
<j sp: useBean i d=" obj " cl ass=" j avabeans. Dat os"
scope=" r equest " / >
<j sp: set Pr oper t y name=" obj " pr oper t y=" numer o" val ue=" 34" / >
<l ogi c: r edi r ect f or war d=" pr ueba"
par amI d=" edad"
par amName=" obj "
par amPr oper t y=" numer o" / >
</ body>
La pgina destino por su parte utilizar las siguientes acciones para mostrar
el contenido del parmetro edad en la pgina, visualizndose: Edad: 34:
<body>
<bean: par amet er i d=" var " name=" edad" / >
Edad: <bean: wr i t e name=" var " / >
</ body>

5.2.8 iterate
Esta accin recorre todos los elementos contenidos en una coleccin,
evaluando para cada uno de ellos el contenido anidado de la accin.
La coleccin sobre la que se va a iterar debe ser de uno de los siguientes
tipos:
Un array de tipos primitivos u objetos J ava.
Un objeto java.util.Collection.
158 STRUTS RA-MA

Un objeto java.util.Enumeration.
Un objeto java.util.Iterator.
Un objeto java.util.Map.
Esta coleccin puede ser especificada de dos posibles maneras, segn cul
de los dos siguientes atributos de <logic:iterate>se emplee:
collection. Representa una expresin J SP que devuelve la
coleccin a recorrer.
name. Nombre del objeto que contiene la coleccin.
En el caso de que se utilice el atributo name, podrn especificarse tambin
los atributos:
property. Nombre de la propiedad del objeto indicado en name
que contiene la coleccin.
scope. mbito del objeto indicado en name.
Aparte de los atributos anteriores, la accin iterate dispone de estos otros:
id. Nombre o identificador de la variable J SP que almacenar la
referencia al elemento de la coleccin en cada iteracin. Su mbito
est limitado a la pgina.
indexId. Nombre o identificador de la variable J SP en donde se
almacenar el ndice de la iteracin en curso. Su mbito est
limitado a la pgina.
type. Nombre cualificado de la clase a la que pertenecen los
elementos de la coleccin.
length. Nmero de iteraciones que se realizarn sobre la coleccin.
Si no se especifica se recorrer completamente la coleccin.
En el siguiente ejemplo se muestra en una pgina la lista de nombres
almacenada en una coleccin de mbito de sesin llamada listado, para, a
continuacin, indicar el nmero de nombres presentados:
<l ogi c: i t er at e name=" l i st ado" scope=" sessi on" i d=" nombr e"
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 159

i ndexI d=" t ot al " >
<bean: wr i t e name=" nombr e" / ><br / >
</ l ogi c: i t er at e>
Tot al de nombr es: <bean: wr i t e name=" t ot al " / >
PRCTICA 5.1. LISTADO DE LLAMADAS CON TAGS STRUTS
Descripcin
Se trata de realizar la misma aplicacin desarrollada en la prctica 4.1,
eliminando los scriptlets de cdigo J ava de las pginas J SP y empleando
nicamente etiquetas XHTML y tags de Struts en su construccin.
Desarrollo
Los nicos componentes que tendremos que modificar respecto a la versin
anterior sern las vistas listado.jsp y opciones.jsp, puesto que login.jsp y
registro.jsp no incluan ningn tipo de scriptlet.
Listados
Seguidamente mostraremos el nuevo contenido de las pginas J SP
mencionadas anteriormente.
opciones.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- l ogi c
pr ef i x=" l ogi c" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
160 STRUTS RA-MA

<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1>Opci ones par a el l i st ado de l l amadas </ h1>
<ht ml : f or mact i on=" / l i st ado" met hod=" POST" >
<b> Sel ecci one nmer o de t el f ono: </ b>
<br / > <br / >
<ht ml : sel ect pr oper t y=" numer o" >
<!--Recupera el bean ValidacionForm
almacenado en una variable de peticin-->
<l ogi c: i t er at e i d=" t el ef ono"
name=" Val i daci onFor m" pr oper t y=" t el ef onos"
t ype=" j ava. l ang. I nt eger " scope=" r equest " >
<opt i on val ue=
" <bean: wr i t e name=' t el ef ono' / >" >
<bean: wr i t e name=" t el ef ono" / >
</ opt i on>
</ l ogi c: i t er at e>
</ ht ml : sel ect >
<br / > <br / > <br / >
<b>Sel ecci one t i po de l l amadas: </ b><br / >
<t abl e>
<t r >
<t d><ht ml : r adi o t abi ndex=" 0"
pr oper t y=" oper aci on" val ue=" t odas" / ></ t d>
<t d al i gn=" l ef t " >Todas</ t d>
</ t r >
<t r >
<t d><ht ml : r adi o pr oper t y=" oper aci on"
val ue=" por t i po" / ></ t d>
<t d al i gn=" l ef t " >Sel ecci one Ti po:
<ht ml : sel ect pr oper t y=" t i po" >
<ht ml : opt i on val ue=" 1" >Nor mal
</ ht ml : opt i on>
<ht ml : opt i on val ue=" 2" >Reduci da
</ ht ml : opt i on>
<ht ml : opt i on val ue=" 3" >Super r educi da
</ ht ml : opt i on>
</ ht ml : sel ect >
</ t d>
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 161

</ t r >
<t r >
<t d><ht ml : r adi o pr oper t y=" oper aci on"
val ue=" por f echa" / ></ t d>
<t d al i gn=" l ef t " >A par t i r de f echa:
<ht ml : t ext pr oper t y=" f echa" / ></ t d>
</ t r >
<t r >
<t d col span=" 2" ><br / >
<ht ml : submi t val ue=" Most r ar l i st ado" / ></ t d>
</ t r >
</ ht ml : f or m>
</ cent er >
</ body>
</ ht ml : ht ml >
listado.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j ava. ut i l . *, j avabeans. *" %>
<%@t agl i b ur i =ht t p: / / j akar t a. apache. or g/ st r ut s/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / j akar t a. apache. or g/ st r ut s/ t ags- l ogi c
pr ef i x=" l ogi c" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1>Li st ado de Ll amadas</ h1>
<t abl e bor der =" 1" wi dt h=" 60%" >
<t h>Tel f ono dest i no</ t h>
<t h>Dur aci n ( segundos) </ t h>
<t h>Tar i f a</ t h>
<t h>Cost e</ t h>
162 STRUTS RA-MA

<t h>Fecha</ t h>
<l ogi c: i t er at e i d=" l l amada" name=" l l amadas"
scope=" r equest " t ype=" j avabeans. Ll amadaBean" >
<t r >
<t d><bean: wr i t e name=" l l amada"
pr oper t y=" dest i no" / ></ t d>
<t d><bean: wr i t e name=" l l amada"
pr oper t y=" dur aci on" / ></ t d>
<t d><bean: wr i t e name=" l l amada"
pr oper t y=" t ar i f a" / ></ t d>
<t d><bean: wr i t e name=" l l amada"
pr oper t y=" cost e" f or mat =" 0. 00" / ></ t d>
<t d><bean: wr i t e name=" l l amada"
pr oper t y=" f echa" / ></ t d>
</ t r >
</ l ogi c: i t er at e>
</ t abl e>
</ cent er >
</ body>
</ ht ml >
PRCTICA 5.2. ENVO Y VISUALIZACIN DE MENSAJES
Descripcin
Se trata en esta prctica de implementar la versin Struts de la aplicacin
para envo y recepcin de mensajes que desarrollamos durante la prctica 1.1. El
aspecto de las pginas ser el mismo que el de esta aplicacin.
Desarrollo
Adems de los componentes Struts del Controlador, en esta versin
utilizaremos los tags de las libreras bean y logic a fin de no tener que incluir
ningn scriptlet de cdigo Java en las pginas.
Las operaciones para la gestin de las acciones grabar mensajes y
recuperar mensajes sern implementadas por dos subclases Action llamadas
EnviarAction y RecuperarAction, respectivamente.
Listado
Seguidamente presentaremos el listado de los diferentes componentes de la
aplicacin, incluido el archivo de configuracin struts-config.xml.
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 163

struts-config.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>

<! DOCTYPE st r ut s- conf i g PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s
Conf i gur at i on 1. 2/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/ st r ut s-
conf i g_1_2. dt d" >
<st r ut s- conf i g>
<f or m- beans>
<f or m- bean name=" Mensaj eFor m"
t ype=" j avabeans. Mensaj eFor m" / >
</ f or m- beans>
<gl obal - f or war ds>
<f or war d name=" pr evi oenvi o" pat h=" / envi o. j sp" / >
<f or war d name=" pr evi ol ect ur a" pat h=" / most r ar . ht m" / >
<f or war d name=" i ni ci o" pat h=" / i ni ci o. j sp" / >
</ gl obal - f or war ds>
<act i on- mappi ngs>
<act i on name=" Mensaj eFor m" pat h=" / gr abar "
scope=" r equest " t ype=" ser vl et s. Envi ar Act i on" >
<f or war d name=" gr abado" pat h=" / i ni ci o. j sp" / >
</ act i on>
<act i on pat h=" / most r ar "
t ype=" ser vl et s. Recuper ar Act i on" >
<f or war d name=" vi sual i za" pat h=" / ver . j sp" / >
<f or war d name=" si nmensaj es"
pat h=" / nomensaj es. j sp" / >
</ act i on>
</ act i on- mappi ngs>
</ st r ut s- conf i g>
MensajeForm.java
package j avabeans;

i mpor t j avax. ser vl et . ht t p. Ht t pSer vl et Request ;
i mpor t or g. apache. st r ut s. act i on. *;

publ i c cl ass Mensaj eFor mext ends Act i onFor m{

164 STRUTS RA-MA

pr i vat e St r i ng r emi t e;
pr i vat e St r i ng dest i no;
pr i vat e St r i ng t ext o;
publ i c Mensaj eFor m( ) {}
//constructor que permite crear un objeto
//Mensaje a partir de los datos del mismo
publ i c Mensaj eFor m( St r i ng r emi t e, St r i ng dest i no,
St r i ng t ext o) {
t hi s. r emi t e=r emi t e;
t hi s. dest i no=dest i no;
t hi s. t ext o=t ext o;
}
publ i c voi d set Remi t e( St r i ng r emi t e) {
t hi s. r emi t e=r emi t e;
}
publ i c St r i ng get Remi t e( ) {
r et ur n t hi s. r emi t e;
}
publ i c voi d set Dest i no( St r i ng dest i no) {
t hi s. dest i no=dest i no;
}
publ i c St r i ng get Dest i no( ) {
r et ur n t hi s. dest i no;
}
publ i c voi d set Text o( St r i ng t ext o) {
t hi s. t ext o=t ext o;
}
publ i c St r i ng get Text o( ) {
r et ur n t hi s. t ext o;
}
}
EnviarAction.java
package ser vl et s;

i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t j avabeans. *;
i mpor t model o. *;
publ i c cl ass Envi ar Act i on ext ends Act i on {
publ i c Act i onFor war d execut e( Act i onMappi ng mappi ng,
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 165

Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Mensaj eFor mmen=( Mensaj eFor m) f or m;
Oper aci ones oper =new Oper aci ones( ) ;
oper . gr abaMensaj e( men) ;
r et ur n mappi ng. f i ndFor war d( " gr abado" ) ;
}
}
RecuperarAction.java
package ser vl et s;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t or g. apache. st r ut s. act i on. *;
i mpor t j ava. ut i l . *;
i mpor t j avabeans. *;
i mpor t model o. *;

publ i c cl ass Recuper ar Act i on ext ends Act i on {
publ i c Act i onFor war d execut e( Act i onMappi ng mappi ng,
Act i onFor m f or m,
Ht t pSer vl et Request r equest ,
Ht t pSer vl et Response r esponse)
t hr ows Except i on {
Oper aci ones oper =new Oper aci ones( ) ;
Ar r ayLi st mensaj es=oper .
obt ener Mensaj es( r equest . get Par amet er ( " nombr e" ) ) ;
//si hay mensajes se visualizan
i f ( mensaj es! =nul l &&mensaj es. si ze( ) >0) {
r equest . set At t r i but e( " mensaj es" , mensaj es) ;
r et ur n mappi ng. f i ndFor war d( " vi sual i za" ) ;
}
el se{
r et ur n mappi ng. f i ndFor war d( " si nmensaj es" ) ;
}
}
}

166 STRUTS RA-MA

Operaciones.java
package model o;
i mpor t j ava. sql . *;
i mpor t j avabeans. *;
i mpor t j ava. ut i l . *;
publ i c cl ass Oper aci ones {
//mtodo comn para la obtencin
//de conexiones
publ i c Connect i on get Connect i on( ) {
Connect i on cn=nul l ;
t r y{
Cl ass. f or Name( " sun. j dbc. odbc. J dbcOdbcDr i ver " ) ;
cn=Dr i ver Manager . get Connect i on( " j dbc: odbc: mensaj es" ) ;
}
cat ch( Except i on e) {e. pr i nt St ackTr ace( ) ; }
r et ur n cn;
}
publ i c Ar r ayLi st obt ener Mensaj es( St r i ng dest i no) {
Connect i on cn=nul l ;
Ar r ayLi st mensaj es=nul l ;
St at ement st ;
Resul t Set r s;
t r y{
cn=get Connect i on( ) ;
st =cn. cr eat eSt at ement ( ) ;
St r i ng t sql ;
t sql =" sel ect * f r ommensaj es wher e
dest i nat ar i o=' " +dest i no+" ' " ;
r s=st . execut eQuer y( t sql ) ;
mensaj es=new Ar r ayLi st ( ) ;
/ / par a cada mensaj e encont r ado cr ea un obj et o
/ / Mensaj e y l o aade a l a col ecci n Ar r ayLi st
whi l e( r s. next ( ) ) {
Mensaj eFor mm=new Mensaj eFor m(
r s. get St r i ng( " r emi t ent e" ) ,
r s. get St r i ng( " dest i nat ar i o" ) ,
r s. get St r i ng( " t ext o" ) ) ;
mensaj es. add( m) ;
}
cn. cl ose( ) ;
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 167

}
cat ch( Except i on e) {e. pr i nt St ackTr ace( ) ; }
r et ur n( mensaj es) ;
}
publ i c voi d gr abaMensaj e( Mensaj eFor mm) {
Connect i on cn;
St at ement st ;
Resul t Set r s;
t r y{
cn=get Connect i on( ) ;
st =cn. cr eat eSt at ement ( ) ;
St r i ng t sql ;
//a partir de los datos del mensaje construye
//la cadena SQL para realizar su inserin
t sql =" I nser t i nt o mensaj es val ues( ' " ;
t sql +=m. get Dest i no( ) +
" ' , ' " +m. get Remi t e( ) +
" ' , ' " +m. get Text o( ) +" ' ) " ;
st . execut e( t sql ) ;
cn. cl ose( ) ;
}
cat ch( Except i on e) {e. pr i nt St ackTr ace( ) ; }
}
}
inicio.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<body>
<cent er >
<br / ><br / >

<ht ml : l i nk f or war d=" pr evi oenvi o" >
Envi ar mensaj e</ ht ml : l i nk>
<br / ><br / >
168 STRUTS RA-MA


<ht ml : l i nk f or war d=" pr evi ol ect ur a" >
Leer mensaj es</ ht ml : l i nk>
</ cent er >
</ body>
</ ht ml : ht ml >
envio.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >

<ht ml : ht ml >
<body>
<cent er >
<h1>Gener aci n de mensaj es</ h1>
<ht ml : f or mact i on=" / gr abar " met hod=" POST" >
<br / ><br / >
<b>Dat os del mensaj e: </ b><br / ><br / >
I nt r oduzca dest i nat ar i o:
<ht ml : t ext pr oper t y=" dest i no" / ><br / >
<br / >
I nt r oduzca r emi t ent e :
<ht ml : t ext pr oper t y=" r emi t e" / ><br / >
<br / >
I nt r oduzca t ext o : <br / >
<ht ml : t ext ar ea pr oper t y=" t ext o" >
</ ht ml : t ext ar ea>
<hr / ><br / >
<ht ml : submi t val ue=" Envi ar " / >
</ ht ml : f or m>
</ cent er >
</ body>
</ ht ml : ht ml >
RA-MA CAPTULO 5. LIBRERAS DE ACCIONES J SP DE STRUTS 169

mostrar.htm
<ht ml >
<body>
<cent er >
<br / ><br / >
<f or mact i on=" most r ar . do" met hod=" post " >
I nt r oduzca su nombr e: <i nput
t ype=" t ext " name=" nombr e" ><br ><br >
<i nput t ype=" submi t " val ue=" Most r ar mensaj es" >
</ f or m>
</ cent er >
</ body>
</ ht ml >
ver.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j avabeans. *, j ava. ut i l . *" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- l ogi c
pr ef i x=" l ogi c" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >

<ht ml : ht ml >
<body>
<cent er >
<bean: par amet er i d=" nombr e" name=" nombr e" / >
<h1>
Mensaj es par a <bean: wr i t e name=" nombr e" / >
</ h1>
<t abl e bor der =" 1" >
<t r ><t h>Remi t ent e</ t h><t h>Mensaj e</ t h></ t r >
<l ogi c: i t er at e i d=" mensaj e" name=" mensaj es"
scope=" r equest " >
<t r ><t d><bean: wr i t e name=" mensaj e"
170 STRUTS RA-MA

pr oper t y=" r emi t e" / ></ t d>
<t d><bean: wr i t e name=" mensaj e"
pr oper t y=" t ext o" / ></ t d>
</ t r >
</ l ogi c: i t er at e>
</ t abl e>
<br / ><br / >
<ht ml : l i nk f or war d=" i ni ci o" >I ni ci o</ ht ml : l i nk>
</ cent er >
</ body>
</ ht ml : ht ml >
nomensajes.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j avabeans. *, j ava. ut i l . *" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- l ogi c
pr ef i x=" l ogi c" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >

<ht ml : ht ml >
<bean: par amet er i d=" nombr e" name=" nombr e" / >
<body>
<cent er >
<h2>
Lo si ent o, <bean: wr i t e name=" nombr e" / > no t i ene mensaj es
</ h2>
<br / ><br / ><br / ><br / >
<ht ml : l i nk f or war d=" i ni ci o" >I ni ci o</ ht ml : l i nk>
</ cent er >
</ body>
</ ht ml : ht ml >



6Captulo 6
VALIDACIN DE DATOS DE USUARIO
La utilizacin del mtodo validate() de ActionForm permite, como hemos
visto en Captulos anteriores, validar los datos suministrados por el usuario a travs
de un formulario XHTML antes de que stos sean procesados por la aplicacin.
Pero este sistema de validacin requiere codificar de forma manual las
instrucciones para la comprobacin de datos, lo que adems de tedioso resulta
ineficiente, ya que la definicin de criterios de validacin idnticos en varios
ActionForm implica la repeticin de las mismas instrucciones de verificacin de
datos en los mtodos validate() de cada una de las clases.
La utilizacin de validadores simplifica enormemente el proceso de
validacin de datos de usuario en una aplicacin Struts al proporcionar un
mecanismo de validacin automtica, de tipo declarativo, que evita la codificacin
de estas tareas desde cdigo, permitiendo adems la validacin de los datos tanto
en el cliente como en el servidor.
6.1 COMPONENTES DE UN VALIDADOR
La utilizacin de validadores en una pgina J SP se apoya en el empleo de
una serie de componentes que proporcionan toda la funcionalidad necesaria para
llevar a cabo la validacin automtica y que habr que configurar adecuadamente
en cada aplicacin, stos componentes son:

172 STRUTS RA-MA

Plug-in validator.
Archivos de configuracin.
La clase ValidatorForm.
Archivo de recursos ApplicationResource.properties.
Veamos a continuacin el significado y funcin de estos componentes
antes de entrar en detalle sobre la manera en que se deben utilizar los validadores.
6.1.1 Plug-in validator
El plug-in validator es la clase incorporada en el API de Struts encargada
de gestionar las validaciones automticas dentro de una aplicacin Web.
Para que puedan utilizarse las validaciones automticas en una determinada
aplicacin ser necesario registrar esta clase en el archivo struts-config.xml
utilizando el elemento <plug-in>:
<pl ug- i n cl assName=
" or g. apache. st r ut s. val i dat or . Val i dat or Pl ugI n" >
<set - pr oper t y
pr oper t y=" pat hnames"
val ue=" / WEB- I NF/ val i dat or - r ul es. xml ,
/ WEB- I NF/ val i dat i on. xml " / >
</ pl ug- i n>
Este elemento dispone de un atributo className en el que se debe
especificar el nombre de la clase Struts.
Se debe indicar adems mediante el subelemento <set-property> las
propiedades necesarias para el funcionamiento del plug-in, si bien en la mayora de
los casos nicamente ser necesario especificar la propiedad pathnames, la cual
debe contener la URL relativa de los archivos de configuracin utilizados por el
plug-in.
6.1.2 Archivos de configuracin
Adems del archivo de configuracin de Struts, struts-config.xml, las
aplicaciones que utilizan validadores necesitan dos archivos de configuracin
adicionales: validator-rules.xml y validation.xml.
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 173

6.1.2.1 VALIDATOR-RULES.XML
A fin de que el programador no tenga que codificar las instrucciones para
la validacin de los datos, Struts incorpora una serie de clases predefinidas cuyos
mtodos realizan las tareas habituales de validacin de datos de usuario requeridas
por la mayora de las aplicaciones Web.
El archivo validator-rules.xml, incluido en el paquete de distribucin de
Struts, contiene la declaracin de estas clases de validacin as como los mtodos
utilizados para realizar cada una de las rutinas de validacin predefinidas,
asociando a cada uno de estos mtodos un nombre lgico que luego podr ser
utilizado para asignar una determinada regla de validacin a un componente
grfico.
El siguiente listado muestra la estructura del archivo validator-rules.xml:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE f or m- val i dat i on PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD Commons
Val i dat or Rul es Conf i gur at i on 1. 1. 3/ / EN"

" ht t p: / / j akar t a. apache. or g/ commons/ dt ds/ val i dat or _1_1_3. dt d" >
<f or m- val i dat i on>
<gl obal >
<val i dat or name=" r equi r ed"
cl assname=" or g. apache. st r ut s.
val i dat or . Fi el dChecks"
met hod=" val i dat eRequi r ed"
met hodPar ams=" j ava. l ang. Obj ect ,
or g. apache. commons.
val i dat or . Val i dat or Act i on,
or g. apache. commons. val i dat or . Fi el d,
or g. apache. st r ut s.
act i on. Act i onMessages,
or g. apache. commons.
val i dat or . Val i dat or ,
j avax. ser vl et . ht t p. Ht t pSer vl et Request "
msg=" er r or s. r equi r ed" / >

:

</ gl obal >
</ f or m- val i dat i on>
174 STRUTS RA-MA

Cada una de estas reglas de validacin se declaran mediante un elemento
<validator>, definindose a travs de sus atributos los parmetros de configuracin
de cada regla. Estos atributos son:
name. Nombre lgico asignado a la regla de validacin.
classname. Nombre de la clase de Struts en la que se encuentran
definidas las instrucciones para realizar la tarea de validacin.
method. Mtodo de la clase indicada en classname que
implementa la regla de validacin.
methodParams. Parmetros declarados por el mtodo y que
necesita para llevar a cabo su funcin. Ser el plug-in validator el
encargado de invocar al mtodo pasndole los argumentos
apropiados en la llamada.
msg. Clave asociada al mensaje de error que se mostrar al usuario
cuando se incumpla el criterio de validacin definido en la regla.
Estos mensajes se registrarn en el archivo
ApplicationResource.properties.
Adems de las reglas de validacin predefinidas por Struts, es posible crear
nuestras propias reglas de validacin personalizadas a fin de poderlas reutilizar en
las aplicaciones. Una vez creadas las clases que implementan estas reglas con sus
respectivos mtodos, ser necesario declararlas en el archivo validator-rules.xml.
Ms adelante en este Captulo analizaremos la creacin de reglas de validacin
personalizadas.
6.1.2.2 VALIDATION.XML
En este archivo de configuracin el programador deber asignar a cada
campo cuyos datos quiera validar la regla o reglas de validacin definidas en el
archivo validator-rules.xml.
En el siguiente listado vemos un ejemplo de definicin de una regla de
validacin sobre un campo de un formulario capturado mediante un ActionForm:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>

<! DOCTYPE f or m- val i dat i on PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD Commons
Val i dat or Rul es Conf i gur at i on 1. 1. 3/ / EN"
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 175

" ht t p: / / j akar t a. apache. or g/ commons/ dt ds/ val i dat or _1_1_3. dt d" >

<f or m- val i dat i on>
<f or mset >
<f or mname=" Regi st r oFor m" >
<f i el d
pr oper t y=" nombr e"
depends=" r equi r ed" >
<ar g key=" Regi st r oFor m. user name" / >
</ f i el d>
</ f or m>
:

</ f or mset >
</ f or m- val i dat i on>
Para cada formulario que se desee validar se definir un elemento <form>,
cuyo atributo name deber contener el nombre del objeto ActionForm encargado
de capturar el dato de usuario. Cada campo que se quiera validar del formulario se
definir en el interior de <form>mediante el elemento <field>.
Ms adelante analizaremos las distintas reglas de validacin personalizadas
proporcionadas por Struts y la forma de utilizarlas.
6.1.3 Clase ValidatorForm
A la hora de definir la clase J avaBean en la que se recogern los datos
procedentes del formulario cliente y de cara a poder utilizar la validacin
automtica proporcionada por los mtodos definidos en validator-rules.xml,
debemos utilizar como clase base ValidatorForm en vez de ActionForm.
La clase ValidatorForm se encuentra definida en el paquete
org.apache.struts.validator y es a su vez una subclase de ActionForm que
proporciona su propia implementacin del mtodo validate(). En ella se invoca a
los distintos mtodos de validacin definidos en validator-rules.xml, segn la
informacin suministrada en validation.xml. Por tanto, a la hora de crear nuestra
propia subclase de ValidatorForm y de cara a utilizar la validacin automtica
proporcionada por los validadores, no tendremos que sobrescribir el mtodo
validate(), debiendo mantenerse la implementacin proporcionada por esta clase
base.
176 STRUTS RA-MA

6.1.4 Archivo ApplicationResource.properties
Como hemos tenido oportunidad de ver en Captulos anteriores, el archivo
de recursos ApplicationResource.properties se utiliza en las aplicaciones Struts
para almacenar cadenas de texto a las que se les asocia una clave, cadenas que
pueden tener diferentes usos dentro de la aplicacin.
En el caso concreto de los validadores se hace uso de este archivo de
recursos para almacenar los mensajes de error devueltos por cada validador cuando
se incumpla el criterio de validacin definido para los campos. El archivo
ApplicationResource.properties, incluido en el paquete de distribucin de Struts,
define una serie de mensajes de error predeterminados para cada uno de los
validadores proporcionados. El siguiente listado muestra el contenido del archivo
de recursos con los mensajes de error incluidos en el mismo y sus claves asociadas:
errors.invalid={0} is invalid.
errors.maxlength={0} can not be greater than {1} characters.
errors.minlength={0} can not be less than {1} characters.
errors.range={0} is not in the range {1} through {2}.
errors.required={0} is required.
errors.byte={0} must be an byte.
errors.date={0} is not a date.
errors.double={0} must be an double.
errors.float={0} must be an float.
errors.integer={0} must be an integer.
errors.long={0} must be an long.
errors.short={0} must be an short.
errors.creditcard={0} is not a valid credit card number.
errors.email={0} is an invalid e-mail address.
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 177

El convenio utilizado a la hora de definir un mensaje de error para un
determinado validador es: errors.nombre_validador. Por supuesto se pueden
modificar estos mensajes y sustituirlos por otros que consideremos ms adecuados,
si bien lo ms conveniente en estos casos ser sobrescribir los mensajes aadiendo
nuevas parejas clave=mensaje, en vez de modificar los predefinidos. Ms adelante
en este Captulo veremos cmo realizar esta tarea.
De cara a poder introducir cierto grado de personalizacin en los mensajes,
cada uno de ellos incluye una serie de parmetros ({0}, {1}, ...) que pueden ser
sustituidos durante el proceso de validacin por valores concretos, tal y como
veremos ms adelante.
6.2 UTILIZACIN DE VALIDADORES
La utilizacin de los mtodos de validacin proporcionados por Struts para
realizar la validacin automtica de los datos de usuario resulta tremendamente
sencilla, consistiendo bsicamente estas tareas en incluir unas pocas instrucciones
de declaracin en un archivo de configuracin.
Para ver el proceso a seguir realizaremos como ejemplo la validacin de
los credenciales de usuario suministrados a travs de una pgina de login, para lo
que partiremos de la pgina login.jsp utilizada en alguna de las prcticas de los
Captulos precedentes. El criterio de validacin que vamos a utilizar en el ejemplo
consistir en verificar que se han suministrado tanto el identificador de usuario
como el password en los campos del formulario, antes de proceder a la
identificacin del usuario en la base de datos.
Como paso previo habr que registrar el plug-in validator en struts-
config.xml, tal y como se mostr en el punto anterior, indicando en la propiedad
pathnames la direccin relativa a la aplicacin Web de los archivos validator-
rules.xml y validation.xml. Habitualmente estos archivos se situarn en el
directorio raiz_aplicacion\WEB-INF, junto con el resto de archivos de
configuracin de la aplicacin. Como archivo validator-rules.xml utilizaremos el
proporcionado por Struts, mientras que validation.xml estar inicialmente vaco.
Despus de realizar estas operaciones previas veremos el resto de pasos a
seguir.
178 STRUTS RA-MA

6.2.1 Creacin de la clase ValidatorForm
La clase ValidacionForm que encapsula los credenciales del usuario deber
heredar ahora ValidatorForm en vez de ActionForm, manteniendo por lo dems los
mismos datos miembro y mtodos set/get que antes:
i mpor t or g. apache. st r ut s. val i dat or . *;
public class ValidacionForm extends ValidatorForm {
//datos miembro
pr i vat e St r i ng usuar i o;
pr i vat e St r i ng passwor d;
/ / mt odos de acceso
publ i c St r i ng get Usuar i o( ) {
r et ur n usuar i o;
}
publ i c voi d set Usuar i o( St r i ng nombr e) {
t hi s. usuar i o = nombr e;
}
publ i c St r i ng get Passwor d( ) {
r et ur n passwor d;
}
publ i c voi d set Passwor d( St r i ng passwor d) {
t hi s. passwor d = passwor d;
}
}
Esta clase deber estar registrada en el archivo struts-config.xml
exactamente igual que cuando heredaba a ActionForm.
6.2.2 Definicin de los criterios de validacin
Para realizar el tipo de validacin indicada anteriormente debemos utilizar
el validador de tipo required, nombre con el que se encuentra registrado el
mtodo de validacin correspondiente en el archivo validator-rules.xml.
Dado que la validacin se va a realizar sobre los campos del objeto
ValidacionForm, tendremos que aadir al archivo validation.xml un elemento
<form>asociado al mismo, elemento que deber estar definido dentro del elemento
<formset>que se incluye a su vez en el elemento raz <form-validation>del
documento:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 179

<! DOCTYPE f or m- val i dat i on PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD
Commons Val i dat or Rul es Conf i gur at i on 1. 1. 3/ / EN"
" ht t p: / / j akar t a. apache. or g/ commons/ dt ds/ val i dat or _1_1_3. dt d" >
<f or m- val i dat i on>
<f or mset >
<f or mname=" Val i daci onFor m" >
:
</ f or m>
</ f or mset >
</ f or m- val i dat i on>

En el interior de <form>incluiremos dos elementos <field>, uno por cada
campo que queremos validar. Cada elemento <field>dispondr de dos atributos:
property. Propiedad del objeto ValidacionForm o nombre del
campo que queremos validar.
depends. Nombre del validador o validadores cuyos criterios de
validacin queremos aplicar sobre el campo, en nuestro caso ser
required para ambos campos. Si queremos aplicar ms de una
regla de validacin sobre un campo, habr que indicar en este
atributo los nombres de todos los validadores separados por una
coma.
Cada elemento <field> incluir adems un elemento <arg> donde se
indicar el argumento correspondiente al parmetro definido en el mensaje de
error. Para ello se debern definir los siguientes atributos del elemento:
key. Nombre de la clave asociada a la cadena que se suministrar
como argumento, cadena que estar definida en
ApplicationResource.properties y cuyo nombre de clave suele
seguir el convenio: objeto_ValidatorForm.campo.
resource. Se trata de un atributo de tipo boolean. Si su valor es
true (es el valor predeterminado en caso de que el atributo no se
utilice) el valor del atributo key ser interpretado como nombre de
clave, mientras que si es false el valor de este atributo ser tomado
como el literal correspondiente al valor del argumento.
Adems de <arg>, un elemento <field>puede incluir opcionalmente los
elementos <arg0>, <arg1>, <arg2>y <arg3>, mediante los cuales se suministrarn
180 STRUTS RA-MA

los argumentos para el resto de parmetros que pudieran incluir los mensajes de
error. Estos elementos disponen de los mismos atributos que <arg>. Si el mensaje
de error requiere nicamente un argumento, puede utilizarse <arg> o <argo>
indistintamente.
Con todo ello, el archivo validation.xml del ejemplo que estamos
analizando quedara:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE f or m- val i dat i on PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD
Commons Val i dat or Rul es Conf i gur at i on 1. 1. 3/ / EN"
" ht t p: / / j akar t a. apache. or g/ commons/ dt ds/ val i dat or _1_1_3. dt d" >
<f or m- val i dat i on>
<f or mset >
<f or mname=" Val i daci onFor m" >
<f i el d
pr oper t y=" usuar i o"
depends=" r equi r ed" >
<ar g key=" Val i daci onFor m. usuar i o" / >
</ f i el d>
<f i el d
pr oper t y=" passwor d"
depends=" r equi r ed" >
<ar g key=" Val i daci onFor m. passwor d" / >
</ f i el d>
</ f or m>
</ f or mset >
</ f or m- val i dat i on>
6.2.3 Habilitacin de la validacin en cliente
Siempre que sea posible se debera realizar la validacin de los datos de
usuario en la pgina cliente, esto har que la peticin de envo de datos al servidor
no sea lanzada en caso de que stos no cumplan con los criterios de validacin
definidos, evitando as la sobrecarga del servidor y mejorando el rendimiento de la
aplicacin.
Pero aunque la validacin en cliente constituye una buena prctica de
programacin, por motivos de seguridad y porque el navegador cliente puede tener
desactivado el uso de J avaScript (que es el lenguaje utilizado por el cdigo cliente
para validar los datos en la pgina Web), ser necesario tambin realizar la
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 181

validacin de los datos en el servidor antes de su procesamiento. Ambos tipos de
validacin, en servidor y en cliente, siguen los criterios definidos en los
validadores, tal y como se ha explicado en las secciones anteriores.
A fin de poder realizar la validacin desde el navegador, el plug-in
validator inyecta una serie de instrucciones J avaScript en la pgina cliente que
sern ejecutadas antes de proceder al envo de la peticin. Pero para que esto
suceda ser necesario habilitar la validacin en cliente aadiendo la siguiente
accin html en cualquier parte de la pgina:
<html:javascript formName="objeto_form"/>
La accin deber indicar a travs del atributo formName el nombre del
objeto ValidatorForm.
As mismo, desde el manejador del evento onsubmit del formulario se
deber incluir una llamada a la funcin J avaScript encargada de desencadenar el
proceso de validacin. Dado que esta funcin se genera de forma dinmica, su
nombre tendr el formato validateObjetoForm, siendo ObjetoForm el nombre del
objeto ValidatorForm. La llamada a ese mtodo incluir como argumento el valor
this. As quedar por tanto la pgina login.jsp del ejemplo:
<ht ml : ht ml >
<body>
<cent er >
<h1>For mul ar i o de aut ent i caci n</ h1>
<html:javascript formName="ValidacionForm"/>
<ht ml : f or mact i on=" / val i dar " met hod=" post "
onsubmi t =" r et ur n val i dat eVal i daci onFor m( t hi s) ; " >
<t abl e>
<t r >
<t d>Usuar i o: </ t d>
<t d><ht ml : t ext pr oper t y=" usuar i o" / ></ t d>
</ t r >
<t r >
<t d>Passwor d: </ t d>
<t d><ht ml : passwor d pr oper t y=" passwor d" / ></ t d>
</ t r >
<t r >
<t d col span=" 2" >
<br / >
<ht ml : submi t pr oper t y=" submi t " val ue=" Val i dar " / >
182 STRUTS RA-MA

&nbsp; &nbsp;
<ht ml : r eset val ue =" Li mpi ar " / >
</ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
<br / >
<ht ml : l i nk f or war d=" par ar egi st r o" >Regi st r ese</ ht ml : l i nk>
<br / ><br / >
<ht ml : er r or s/ >
</ cent er >
</ body>
</ ht ml : ht ml >
6.2.4 Mensajes de error
El mensaje de error que se mostrar al usuario en caso de incumplirse el
criterio de validacin es, en este ejemplo, el que viene definido con la clave
errors.required en el archivo ApplicationResource.properties:
errors.required={0} is required.
Ser tambin en este archivo donde se definan las cadenas que se pasarn
como argumento al mensaje de error para cada control:
ValidacionForm.usuario="usuario"
ValidacionForm.password="password"
A la hora de mostrar los mensajes de error, cuando la validacin se produce
en cliente se mostrar un cuadro de dilogo con el mensaje correspondiente en el
momento en que se intente realizar la peticin desde la pgina (figura 30).
Con la validacin en el servidor, en caso de que los datos no cumplan con
los criterios definidos por los validadores, el usuario es redireccionado a la pgina
desde la que se produjo el envo de los datos. Los mensajes de error se mostrarn
entonces en aquellas zona de la pgina donde se encuentre situada la accin
<html:errors>.


RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 183









Fig. 30. Mensaje de error de validacin
6.3 VALIDADORES PREDEFINIDOS DE STRUTS
Ya hemos visto el funcionamiento de uno de los validadores clsicos que
se utilizan en la mayora de las aplicaciones Web, el validador required.
Seguidamente analizaremos otros de los validadores proporcionados por Struts que
se emplean con ms frecuencia en las aplicaciones.
6.3.1 minlength
Este validador comprueba que el valor numrico suministrado en un campo
sea mayor o igual a una determinada constante.
Adems de los subelementos <argn>, el elemento <field>utilizado en la
declaracin de este validador en validation.xml deber incluir un subelemento
<var>en el que se indique la constante con la que se comparar el valor del campo.
La estructura de este elemento es:
<var>
<var-name>nombre</var-name>
<var-value>valor</var-value>
</var>
184 STRUTS RA-MA

donde <var-name>contiene el nombre de la constante (en el caso de minlength el
nombre de la variable ser el mismo, minlength) y <var-value>su valor.
El siguiente ejemplo define una regla de validacin para el campo edad
de un formulario, que fuerza al usuario a la introduccin de un valor en el mismo
igual o superior a 18:
<f i el d
pr oper t y=" edad"
depends=" mi nl engt h" >
<ar g0 key=" Regi st r oFor m. edad" / >
<ar g1 key=" Regi st r oFor m. edad. mi n" / >
<var >
<var - name>mi nl engt h</ var - name>
<var - val ue>18</ var - val ue>
</ var >
</ f i el d>
En este validador vemos cmo el mensaje de error requiere de dos
argumentos, el nombre del campo y el valor mnimo.
6.3.2 maxlength
Su estructura es igual a la de minlength, validando el campo indicado en el
atributo property de <field>si su valor es igual o inferior a la constante indicada en
el elemento <var>. El siguiente ejemplo establece que el valor del campo limite
debe ser igual o inferior a 600:
<f i el d
pr oper t y=" l i mi t e"
depends=" r equi r ed, maxl engt h" >
<ar g0 key=" I nf oFor m. l i mi t e" / >
<ar g0 name=" maxl engt h" key=" I nf oFor m. l i mi t e" / >
<ar g1 name=" maxl engt h" key=" I nf oFor m. l i mi t e. max" / >
<var >
<var - name>maxl engt h</ var - name>
<var - val ue>600</ var - val ue>
</ var >
</ f i el d>
En el ejemplo anterior vemos cmo en el mismo elemento <field>se
definen dos validadores para el mismo campo. En estos casos, el atributo name del
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 185

elemento <argn>permite indicar el tipo de validador al que est asociado el
argumento.
6.3.3 byte, short, integer, long, float y double
Mediante estos validadores podemos comprobar si el contenido de un
campo es compatible con el tipo de dato representado por el validador. Por
ejemplo, la siguiente regla comprueba que el dato suministrado en el campo
saldo sea de tipo double:
<f i el d
pr oper t y=" sal do"
depends=" doubl e" >
<ar g key=" Cuent aFor m. sal do " / >
</ f i el d>
6.3.4 intRange
El validador intRange comprueba que el valor del campo se encuentra
comprendido dentro de un determinado rango numrico entero, cuyos valores
mximo y mnimo estarn determinados por los subelementos <var>llamados
max y min.
La siguiente regla permite verificar que el valor del campo nota est
comprendido entre 1 y 10:
<f i el d
pr oper t y=" not a"
depends=" i nt Range" >
<ar g0 key=" I nf oFor m. not a" / >
<ar g1 key=" I nf oFor m. not a. mi n" / >
<ar g2 key=" I nf oFor m. not a. max" / >
<var >
<var - name>mi n</ var - name>
<var - val ue>1</ var - val ue>
</ var >
<var >
<var - name>max</ var - name>
<var - val ue>10</ var - val ue>
</ var >
</ f i el d>
186 STRUTS RA-MA

Como se puede observar en el ejemplo y tambin en el archivo de recursos
ApplicationResource.properties, el mensaje de error asociado a este validador
necesita tres parmetros: el nombre del campo, el valor mnimo y el mximo. Los
argumentos que se utilizan en el ejemplo se encontraran almacenados en el archivo
de recursos con las claves InforForm.nota, InfoForm.nota.min e
InfoForm.nota.max, respectivamente.
6.3.5 floatRange y doubleRange
Al igual que el anterior, estos validadores comprueban que el valor del
campo se encuentra delimitado dentro de un determinado rango numrico, slo que
en estos caso ese rango es de tipo float y double, respectivamente. La estructura del
elemento <field>es exactamente igual a la de intRange.
6.3.6 date
Comprueba que el valor del campo tiene un formato de fecha vlido:
<f i el d
pr oper t y=" f echai ni ci o"
depends=" dat e" >
<ar g key=" Empl eadoFor m. f echa" / >
</ f i el d>
Opcionalmente el elemento <field> admite una variable, llamada
datePattern, mediante la que se puede especificar el tipo de formato de fecha
admitida para el campo. Por ejemplo, la siguiente regla establece para el campo
fechainicio el formato de tipo da/mes/ao:
<f i el d
pr oper t y=" f echai ni ci o"
depends=" dat e" >
<ar g key=" Empl eadoFor m. f echa" / >
<var >
<var - name>dat ePat t er n</ var - name>
<var - val ue>dd/ MM/ yyyy</ var - val ue>
</ var >
</ f i el d>
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 187

6.3.7 mask
A travs de este validador obligamos a que el contenido de un campo se
ajuste al formato definido en una mscara. Esta mscara estar definida dentro de
la variable mask. Para definir una mscara utilizaremos las reglas de
construccin de aplicaciones regulares en J ava. Por ejemplo, la siguiente regla de
validacin establece que el contenido del campo url debe ser la direccin de un
dominio .com:
<f i el d
pr oper t y=" ur l "
depends=" mask" >
<ar g key=" Empr esaFor m. ur l " / >
<var >
<var - name>mask</ var - name>
<var - val ue>www\ . . +\ . com</ var - val ue>
</ var >
</ f i el d>
6.3.8 email
Otro de los campos habituales que nos podemos encontrar en un formulario
cliente es la direccin de correo electrnico. Mediante este validador y sin
necesidad de proporcionar ningn tipo de informacin adicional, se comprueba que
la cadena de caracteres almacenada en un determinado campo se ajusta al formato
de direccin de correo:
<f i el d
pr oper t y=" cor r eo"
depends=" emai l " >
<ar g key=" Empl eadoFor m. emai l " / >
</ f i el d>
6.4 MENSAJES DE ERROR PERSONALIZADOS
Si queremos modificar los mensajes de error que se muestran al usuario
cuando el campo incumple un criterio de validacin, la mejor forma de hacerlo ser
seguir los siguientes pasos:
Aadir el mensaje al archivo de recursos. En el archivo de
recursos ApplicationResource.properties escribiramos el mensaje
personalizado que queremos mostrar, asignndole una clave al
188 STRUTS RA-MA

mismo. Dado que los mensajes predefinidos tienen como clave
asociadas: errors.nombre_validador, deberamos utilizar un
convenio diferente para las claves personalizadas, como por
ejemplo: errors.personalizados.nombre_validador.
Indicar el mensaje a utilizar en <field>. Para indicar que en la
validacin de un determinado campo se va a utilizar un mensaje de
error distinto al predeterminado, debemos emplear el subelemento
<msg>de <field>, indicando mediante sus atributos name y key el
nombre del validador al que se asocia el mensaje (slo es necesario
cuando se definen ms de un validador para el campo) y la clave
del mismo, respectivamente. En el siguiente ejemplo asociamos un
mensaje de error personalizado con la validacin de una direccin
de correo electrnico:
<f i el d
pr oper t y=" cor r eo"
depends=" emai l " >
<msg key=" er r or s. per sonal i zados. emai l " / >
<ar g0 key=" Empl eadoFor m. emai l " / >
</ f i el d>
Los argumentos indicados en <argn>se referirn en estos casos al
nuevo mensaje definido.
PRCTICA 6.1. VALIDACIN DE LOS CAMPOS DE LA PGINA
DE REGISTRO
Descripcin
Utilizando los validadores proporcionados por Struts vamos a definir una
serie de reglas de validacin para cada uno de los seis campos incluidos en una
pgina de registro de usuarios como la que se indica en la figura 31.
Los criterios para considerar como vlidos los datos suministrados a travs
de estos campos sern los siguientes:
Todos los campos sern de obligada cumplimentacin.
El campo password tendr que tener una longitud mnima de
cuatro caracteres.
El campo edad deber ser de tipo entero.
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 189

El campo email tendr que tener una direccin de correo con
formato vlido.









Fig. 31. Pgina de registro de usuarios
Desarrollo
Segn los criterios anteriores, todos los campos debern tener asignado el
validador required. Adems de ste, los campos password, edad e email
debern tener asignado el validado minlength, integer e email, respectivamente.
Para realizar nicamente la tareas de validacin de datos no ser necesario
incluir ninguna sentencia de cdigo J ava, tan slo ser necesario asignar en
validation.xml los validadores indicados a cada control.
Por otro lado, tambin ser necesario registrar en el archivo de recursos
ApplicationResource.properties el texto que se utilizar como argumento en los
mensajes de error para cada control.
En cuanto a la pgina registro.jsp, aadiremos las instrucciones necesarias
para habilitar la validacin en cliente, as como el volcado de los mensajes de error
en la pgina para la validacin en servidor.


190 STRUTS RA-MA

Listado
Seguidamente mostraremos el cdigo de los archivos de texto relacionados
con la validacin.
ApplicationResource.properties
Ser necesario aadir a este archivo las siguientes lneas de texto:
Regi st r oFor m. nombr e=" nombr e"
Regi st r oFor m. apel l i dos=" apel l i dos"
Regi st r oFor m. usuar i o=" nombr e"
Regi st r oFor m. passwor d=" passwor d"
Regi st r oFor m. edad=" edad"
Regi st r oFor m. emai l =" emai l "
Regi st r oFor m. passwor d. mi n=" 4"
validation.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>

<! DOCTYPE f or m- val i dat i on PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD Commons
Val i dat or Rul es Conf i gur at i on 1. 1. 3/ / EN"

" ht t p: / / j akar t a. apache. or g/ commons/ dt ds/ val i dat or _1_1_3. dt d" >

<f or m- val i dat i on>
<f or mset >
<f or mname=" Regi st r oFor m" >
<f i el d
pr oper t y=" nombr e"
depends=" r equi r ed" >
<ar g key=" Regi st r oFor m. nombr e" / >
</ f i el d>
<f i el d
pr oper t y=" apel l i dos"
depends=" r equi r ed" >
<ar g key=" Regi st r oFor m. apel l i dos" / >
</ f i el d>
<f i el d
pr oper t y=" usuar i o"
depends=" r equi r ed" >
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 191

<ar g key=" Regi st r oFor m. usuar i o" / >
</ f i el d>
<f i el d
pr oper t y=" passwor d"
depends=" r equi r ed, mi nl engt h" >
<ar g0 key=" Regi st r oFor m. passwor d" / >
<ar g1 name=" mi nl engt h"
key=" Regi st r oFor m. passwor d. mi n" / >
<var >
<var - name>mi nl engt h</ var - name>
<var - val ue>4</ var - val ue>
</ var >
</ f i el d>
<f i el d
pr oper t y=" edad"
depends=" r equi r ed, i nt eger " >
<ar g0 key=" Regi st r oFor m. edad" / >
<ar g1 key=" Regi st r oFor m. edad" / >
</ f i el d>
<f i el d
pr oper t y=" emai l "
depends=" r equi r ed, emai l " >
<ar g0 key=" Regi st r oFor m. emai l " / >
</ f i el d>
</ f or m>
</ f or mset >
</ f or m- val i dat i on>
registro.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >

<ht ml : ht ml >
<body>
<cent er >
<h1>Regi st r o de usuar i os</ h1>
192 STRUTS RA-MA

<ht ml : j avascr i pt f or mName=" Regi st r oFor m" / >
<ht ml : f or mact i on=" / r egi st r ar " met hod=" POST"
onsubmi t =" r et ur n val i dat eRegi st r oFor m( t hi s) ; " >
<t abl e>
<t r >
<t d>Nombr e: </ t d>
<t d><ht ml : t ext pr oper t y=" nombr e" / ></ t d>
</ t r >
<t r >
<t d>Apel l i dos: </ t d>
<t d><ht ml : t ext pr oper t y=" apel l i dos" / ></ t d>
</ t r >
<t r >
<t d>Usuar i o: </ t d>
<t d><ht ml : t ext pr oper t y=" usuar i o" / ></ t d>
</ t r >
<t r >
<t d>Passwor d: </ t d>
<t d><ht ml : passwor d pr oper t y=" passwor d" / ></ t d>
</ t r >
<t r >
<t d>Edad: </ t d>
<t d><ht ml : t ext pr oper t y=" edad" / ></ t d>
</ t r >
<t r >
<t d>Emai l : </ t d>
<t d><ht ml : t ext pr oper t y=" emai l " / ></ t d>
</ t r >
<t r >
<t d col span=" 2" >
<br / >
<ht ml : submi t pr oper t y=" submi t " val ue=" Regi st r ar " / >
&nbsp; &nbsp;
<ht ml : r eset val ue =" Li mpi ar " / >
</ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
<br / >
<ht ml : er r or s/ >
</ cent er >
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 193

</ body>
</ ht ml : ht ml >
6.5 VALIDACIONES PERSONALIZADAS
En algunas ocasiones puede ocurrir que con los validadores predefinidos de
Struts no cubramos todas las necesidades de validacin para los campos de nuestra
aplicacin.
En estos casos, si tuviramos que aplicar una regla de validacin no
incluida en los validadores de Struts, podemos optar por una de las siguientes
soluciones:
Sobrescribir el mtodo validate() del ValidatorForm para incluir
nuestras propias instrucciones de la validacin.
Definir un mtodo validador personalizado.
6.5.1 Sobrescritura del mtodo validate()
Anteriormente comentamos que a la hora de crear la clase bean que
heredase ValidatorForm debamos mantener la implementacin por defecto del
mtodo validate() proporcionado por esta clase base.
Si queremos incluir algn criterio de validacin personalizado en nuestra
clase y, al mismo tiempo, mantener la validacin automtica proporcionada por
Struts, podemos sobrescribir en nuestra clase ValidatorForm el mtodo validate() e
incluir manualmente en l las instrucciones de validacin propias, siempre y
cuando agreguemos tambin a ste una llamada al mtodo validate() de la
superclase.
El formato de mtodo validate() proporcionado por ValidatorForm y que
podemos sobrescribir es el siguiente:
public ActionErrors validate(ActionMapping mapping,
javax.servlet.http.HttpServletRequest request)
Por ejemplo, supongamos que en la pgina registro.jsp de la prctica
anterior quisiramos incluir un campo adicional (llamado passwordrep) donde el
usuario deba volver a introducir el password por segunda vez, comprobando a
194 STRUTS RA-MA

continuacin que el valor introducido en el segundo campo coincide con el del
primero.
Dado que este criterio de validacin no es implementado por ninguno de
los validadores proporcionados por Struts, deberamos sobrescribir el mtodo
validate() de nuestra subclase RegistroForm e incluir en l las instrucciones
necesarias para realizar esta comprobacin. El siguiente listado muestra cmo
quedara la nueva implementacin de la clase RegistroForm, indicando en fondo
sombreado las instrucciones aadidas:
package j avabeans;
i mpor t or g. apache. st r ut s. val i dat or . *;
publ i c cl ass Regi st r oFor mext ends Val i dat or For m{
pr i vat e St r i ng nombr e;
pr i vat e St r i ng apel l i dos;
pr i vat e St r i ng usuar i o;
pr i vat e St r i ng passwor d;
pr i vat e St r i ng passwor dr ep;
pr i vat e St r i ng emai l ;
publ i c St r i ng get Nombr e( ) {
r et ur n nombr e;
}
publ i c voi d set Nombr e( St r i ng nombr e) {
t hi s. nombr e = nombr e;
}
publ i c St r i ng get Apel l i dos( ) {
r et ur n apel l i dos;
}
publ i c voi d set Apel l i dos( St r i ng apel l i dos) {
t hi s. apel l i dos = apel l i dos;
}
publ i c St r i ng get Usuar i o( ) {
r et ur n usuar i o;
}
publ i c voi d set Usuar i o( St r i ng usuar i o) {
t hi s. usuar i o = usuar i o;
}
publ i c St r i ng get Passwor d( ) {
r et ur n passwor d;
}


RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 195

publ i c voi d set Passwor d( St r i ng passwor d) {
t hi s. passwor d = passwor d;
}
publ i c St r i ng get Passwor dr ep( ) {
r et ur n passwor dr ep;
}
publ i c voi d set Passwor dr ep( St r i ng passwor dr ep) {
t hi s. passwor dr ep = passwor dr ep;
}
publ i c St r i ng get Emai l ( ) {
r et ur n emai l ;
}
publ i c voi d set Emai l ( St r i ng emai l ) {
t hi s. emai l = emai l ;
}
publ i c Act i onEr r or s val i dat e( Act i onMappi ng mappi ng,
Ht t pSer vl et Request r eq) {
Act i onEr r or s er r or s=super . val i dat e( mappi ng, r eq) ;
i f ( ! passwor d. equal s( passwor dr ep) ) {
er r or s. add( " passwor d" ,
new Act i onMessage( " er r or . passwor d. nomat ch" ) ) ;
}
r et ur n er r or s;
}
}
6.5.2 Creacin de validadores personalizados
Si queremos definir una regla de validacin que pueda ser utilizada en
diversos proyectos, la solucin ser crear nuestro propio mtodo validador. Esta
operacin requiere realizar las siguientes tareas:
Implementar el mtodo de validacin.
Registrar el validador en validator-rules.xml.
Definir los mensajes de error predefinidos.
Utilizar el validador.
Implementacin de un mtodo de validacin.
196 STRUTS RA-MA

6.5.2.1 IMPLEMENTACIN DEL MTODO DE VALIDACIN
En una clase estndar de J ava implementaremos el mtodo que deber ser
invocado por Struts para validar el contenido de un campo asociado al mismo,
incluyendo en dicho mtodo la lgica necesaria para la comprobacin de los datos
segn nuestras propias reglas personalizadas.
El mtodo podr llamarse de cualquier forma, si bien deber respetar el
siguiente formato:
public boolean nombre_metodo(Object ob,
org.apache.commons.validator.ValidatorAction v,
org.apache.commons.validator.Field f,
org.apache.struts.action.ActionMessages msgs,
org.apache.commons.validator.Validator vt,
javax.servlet.http.HttpServletRequest request)
Como vemos, el mtodo deber declarar seis parmetros cuyo significado
es el siguiente:
Object. Objeto bean que contiene el campo que ser validado.
ValidatorAction. Representa el elemento <validator>definido en
validator-rules.xml, asociado a esta regla de validacin.
Field. Representa el elemento <field>definido en validation.xml,
asociado al campo que est siendo validado.
ActionMessages. Contiene los mensajes de error asociados al
campo que se est validando.
Validator. Instancia actual del objeto Validator que controla el
proceso de validacin
HttpServletRequest. Objeto que contiene los datos de la peticin
en curso.
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 197

Por otro lado, el mtodo deber devolver un valor de tipo boolean que
indicar a Struts el resultado de la validacin (true validacin correcta, false
validacin incorrecta).
Por ejemplo, supongamos que quisiramos crear una regla de validacin
especial para las contraseas suministradas mediante un formulario cliente,
consistente en obligar al usuario a incluir un carcter de puntuacin en la misma,
carcter que limitaremos a uno de los siguientes: ., , o -. Dicha regla de
validacin la incluiremos dentro de un mtodo llamado passwordValida que
implementaremos en una clase llamada Personalizado. He aqu el cdigo de la
clase:
package val i dador es;
i mpor t or g. apache. commons. val i dat or . ut i l . *;
publ i c cl ass Per sonal i zado {
publ i c bool ean passwor dVal i da( Obj ect ob,
or g. apache. commons. val i dat or . Val i dat or Act i on v,
or g. apache. commons. val i dat or . Fi el d f ,
or g. apache. st r ut s. act i on. Act i onMessages msgs,
or g. apache. commons. val i dat or . Val i dat or vt ,
j avax. ser vl et . ht t p. Ht t pSer vl et Request r equest ) {
St r i ng s=Val i dat or Ut i l s.
get Val ueAsSt r i ng( ob, f . get Pr oper t y( ) ) ;
i f ( s. cont ai ns( " . " ) | | s. cont ai ns( " , " ) | |
s. cont ai ns( " - " ) ) {
/ / cont r asea vl i da
r et ur n t r ue;
}
el se{
r et ur n f al se;
}
}
}
Como podemos apreciar en este cdigo, hacemos uso del mtodo esttico
getValueAsString() incluido en la clase ValidatorUtils para recuperar el valor
contenido en el campo a validar, mtodo que requiere el bean donde se encuentra
incluido el campo y la propiedad que lo define, la cual puede obtenerse a partir del
objeto Field.
198 STRUTS RA-MA

6.5.2.2 REGISTRO DEL VALIDADOR
Una vez definido el mtodo debemos registrar la nueva regla de validacin
en el archivo de configuracin validator-rules.xml de la aplicacin en donde
queramos hacer uso de ella. Para ello, debemos aadir un nuevo elemento
<validator>con los datos del validador, como son el nombre asignado al mismo, el
mtodo que implementa la regla de validacin y la clase donde est definido, los
parmetros que recibir el mtodo y la clave asociada al mensaje de error. Estos
datos se suministrarn a travs de los atributos de <validator> analizados al
principio del Captulo.
As mismo, se deber incluir dentro del elemento <validator> un
subelemento <javascript>en el que se defina la funcin javascript que tendr que
ser ejecutada por el navegador para realizar la validacin en cliente. A esta funcin
se le asigna normalmente el mismo nombre que al mtodo de la clase de servidor.
La informacin a incluir en validator-rules.xml para el caso del ejemplo
que se est analizando se muestra en el siguiente listado:
<val i dat or name=" pwdVal i d"
cl assname=" val i dador es. Per sonal i zado"
met hod=" passwor dVal i da"
met hodPar ams=" j ava. l ang. Obj ect ,
or g. apache. commons. val i dat or . Val i dat or Act i on,
or g. apache. commons. val i dat or . Fi el d,
or g. apache. st r ut s. act i on. Act i onMessages,
or g. apache. commons. val i dat or . Val i dat or ,
j avax. ser vl et . ht t p. Ht t pSer vl et Request "
depends=" "
msg=" er r or s. pwd" >
<j avascr i pt >
<! [ CDATA[
f unct i on passwor dVal i da( f or m) {
var bVal i d = f al se;
var f ocusFi el d = nul l ;
var i = 0;
var f i el ds = new Ar r ay( ) ;
var f or mName = f or m. get At t r i but eNode( " name" ) ;
oPwd = eval ( ' new ' +
f or mName. val ue + ' _pwdVal i d( ) ' ) ;
f or ( x i n oPwd) {
var f i el d = f or m[ oPwd[ x] [ 0] ] ;
RA-MA CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 199

/ / compr obaci n de t i po de campo
i f ( ( f i el d. t ype == ' hi dden' | |
f i el d. t ype == ' t ext ' | |
f i el d. t ype == ' t ext ar ea' | |
f i el d. t ype == ' passwor d' | |
f i el d. t ype == ' sel ect - one' | |
f i el d. t ype == ' r adi o' ) &&
f i el d. di sabl ed == f al se) {
var val ue = ' ' ;
/ / obt i ene el val or del campo
val ue = f i el d. val ue;
/ / apl i ca l a r egl a de val i daci n
i f ( val ue. l engt h > 0) {
f ocusFi el d = f i el d;
f i el ds[ i ++] =oPwd[ x] [ 1] ;
i f ( val ue. i ndexOf ( " . " ) ! =- 1| |
val ue. i ndexOf ( " , " ) ! =- 1| |
val ue. i ndexOf ( " - " ) ! =- 1) {
bVal i d=t r ue;
}
}
}
}
i f ( ( f i el ds. l engt h > 0) &&! bVal i d) {
f ocusFi el d. f ocus( ) ;
al er t ( f i el ds. j oi n( ' \ n' ) ) ;
}
r et ur n bVal i d;
}] ] >
</ j avascr i pt >
</ val i dat or >
Para definir la funcin J avaScript anterior podemos utilizar como modelo
cualquiera de las que utilizan los validadores proporcionados por Struts. Toda
funcin de validacin deber cumplir dos mnimas reglas, la primera es que deber
declarar un parmetro en el que recibir el formulario con el campo a validar, y la
segunda es que la funcin deber devolver un valor de tipo boolean que informe
del resultado de la validacin.
200 STRUTS RA-MA

6.5.2.3 MENSAJES DE ERROR
Los mensajes de error por defecto asociados al validador se incluirn en el
archivo ApplicationResource de la aplicacin. Para realizar la asociacin se
indicar en el atributo msg del elemento <validator>el nombre de la clave que se le
ha asociado. Este mensaje puede incluir parmetros si as lo deseamos. La siguiente
lnea correspondera al mensaje asociado al validador del ejemplo:
errors.pwd=Un password debe contener signos de puntuacin
6.5.2.4 UTILIZACIN DEL VALIDADOR
Una vez registrada la regla de validacin, para poder hacer uso de la misma
en una aplicacin hay que seguir exactamente los mismos pasos que indicamos con
los validadores predefinidos de Struts, esto es, tendremos que asociar la regla al
campo que queramos validar dentro del archivo validation.xml y activar, si
procede, en la pgina J SP la validacin en cliente.
En el ejemplo que estamos tratando, si quisiramos validar el campo
password de un formulario con la nueva regla que hemos definido, tendremos que
aadir el siguiente elemento <field>al archivo validation.xml:
<f or mname=" Regi st r oFor m" >
:
<f i el d
pr oper t y=" passwor d"
depends=" pwdVal i d" >
<ar g key=" Regi st r oFor m. passwor d" / >
</ f i el d>
</ f or m>
En cuanto a la activacin de la validacin en cliente, incluiremos la
siguiente definicin en la pgina J SP:
<h1>Regi st r o de usuar i os</ h1>
<html:javascript formName="RegistroForm"/>
<ht ml : f or mact i on=" / r egi st r ar " met hod=" POST"
onsubmi t =" r et ur n val i dat eRegi st r oFor m( t hi s) ; " >
:
La funcin validateRegistroFor(), invocada desde el manejador de evento
onsubmit del formulario, es generada dinmicamente por Struts. El nombre de esta
funcin deber tener siempre el formato validateObjetoForm.


7Captulo 7
UTILIZACIN DE PLANTILLAS
Las plantillas o tiles, como habitualmente se les conoce en Struts, fueron
incorporados al ncleo de la especificacin a partir de la versin 1.1.
Su objetivo no es otro que posibilitar la reutilizacin de cdigo
XHTML/J SP durante el desarrollo de la Vista en una aplicacin Web MVC,
simplificando el desarrollo de las pginas y haciendo tambin ms cmodos y
menos propensos a errores los posibles cambios que se puedan realizar a posteriori
sobre esta capa de la aplicacin.
La utilizacin de plantillas resulta adecuada por tanto en aquellas
aplicaciones Web en las que tenemos un grupo de pginas con estructura similar,
en las que el contenido de ciertas partes de las mismas es igual en todas ellas.






Fig. 32. Clsico tipo de pginas para utilizacin de plantillas
Encabezado de pgina
Men superior
M
e
n


l
a
t
e
r
a
l
Cuerpo de pgina
Pie de pgina
202 STRUTS RA-MA

Este es el caso de las pginas que suelen tener la tpica estructura que se
muestra en la figura 32, donde la zona de encabezado, pie y men suele ser idntica
para un cierto grupo de pginas de la aplicacin, cambiando slo el cuerpo de una a
otra.
7.1 CONFIGURACIN DE LA APLICACIN PARA EL
USO DE PLANTILLAS
Para poder utilizar plantillas en una aplicacin Struts es necesario realizar
dos operaciones previas en el archivo de configuracin struts-config.xml.
La primera de ellas consiste en indicar al Controlador de Struts que debe
utilizar un objeto RequestProcessor a partir de una clase diseada explcitamente
para el uso de plantillas, como es el caso de la clase TilesRequestProcessor que se
encuentra en el paquete org.apache.struts.tiles. As pues, debemos aadir la
siguiente entrada en el archivo de configuracin struts-config.xml, a continuacin
del elemento <action-mappings>:
<cont r ol l er pr ocessor Cl ass=
" or g. apache. st r ut s. t i l es. Ti l esRequest Pr ocessor " / >
La segunda de las operaciones previas ser la activacin del plug-in tiles
encargado de gestionar las plantillas. Para ello aadiremos la siguiente entrada en
struts-config.xml:
<pl ug- i n cl assName=" or g. apache. st r ut s. t i l es. Ti l esPl ugi n" >
<set - pr oper t y pr oper t y=" def i ni t i ons- conf i g"
val ue=" / WEB- I NF/ t i l es- def s. xml " / >
<set - pr oper t y pr oper t y=" modul eAwar e" val ue=" t r ue" / >
</ pl ug- i n>
Los elementos anteriores se encuentran ya incluidos de forma
predeterminada en el archivo struts-config.xml que se proporciona con el paquete
de distribucin de Struts, por lo que no ser necesario aadirlos de forma manual.
7.2 CREACIN DE UNA APLICACIN STRUTS BASADA
EN PLANTILLAS
La idea bsica en la que se fundamenta este tipo de aplicaciones consiste
en la definicin de una plantilla o pgina maestra en la que se define una
RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 203

determinada estructura tipo de pgina, indicando las distintas zonas en la que stas
estarn divididas y la distribucin de las mismas.
Esta pgina maestra sirve de base para la creacin de las pginas J SP que
forman la vista de la aplicacin, en la que nicamente habr que indicar el
contenido que debe ser incluido dentro de cada zona.
Tanto la creacin de la pgina maestra como de las pginas de aplicacin
requieren de la utilizacin de la librera de acciones tiles incluida en el ncleo de
Struts, por lo que habr que aadir la siguiente directiva taglib al principio de cada
una de las pginas:
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>
A continuacin analizaremos en detalle los pasos a seguir en la
construccin de este tipo de aplicaciones.
7.2.1 Creacin de la plantilla
Como acabamos de comentar, la plantilla ser implementada mediante una
pgina J SP, dicha pgina deber estar situada en el directorio privado de la
aplicacin WEB-INF a fin de que no pueda ser accesible directamente desde el
navegador cliente.
Utilizaremos etiquetas XHTML estndares para indicar el contenido
esttico que va a ser idntico en todas las pginas, as como las acciones y scriptlets
J SP que deben ser ejecutados en todas ellas.
En cuanto a las zonas de contenido dependiente de cada pgina, debern
ser marcadas mediante dos posibles tipos de acciones tiles:
insert. Esta accin tiene diversos usos como iremos viendo a lo
largo del Captulo. En las pginas maestras se utiliza para indicar
la existencia de una seccin de contenido, seccin a la que se le
asignar un nombre mediante el atributo attribute de la accin. El
siguiente ejemplo define una seccin de contenido llamada
header, situada dentro de una etiqueta <div>:
<div><tiles:insert attribute="header"></div>
204 STRUTS RA-MA

Durante la creacin de las pginas de la aplicacin estas secciones
sern sustituidas por el contenido definido en determinados
ficheros externos, habitualmente pginas J SP.
getAsString. Define una seccin de texto, utilizando el atributo
name para asignar el nombre a la seccin:
<h1><tiles:getAsString name="titulo"/></h1>
Como sucede con <tiles:insert>, ser durante la creacin de la
pgina de aplicacin cuando esta accin sea sustituida por un texto
real.
Vamos a ver un ejemplo concreto que sirva para aclarar conceptos.
Imaginemos que queremos crear una aplicacin con dos pginas cuyo aspecto se
muestra en la figura 33.







Fig. 33. Pginas de aplicacin de ejemplo
Como vemos, ambas pginas estn organizadas en cuatro zonas: un texto
en la parte superior, que es distinto para cada pgina, un encabezado, un men en el
lateral izquierdo, ambos idnticos en las dos pginas, y un cuerpo que ocupa la
parte central de la pgina y que tambin estar personalizado para cada una de
ellas.
La plantilla que define la organizacin anterior quedara tal y como se
indica en el siguiente listado:
<%@page cont ent Type=" t ext / ht ml " %>
RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 205

<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e><tiles:getAsString name="titulo"/></ t i t l e>
</ head>
<body>
<cent er >
<h1><t i l es: get AsSt r i ng name=" t i t ul o" / ></ h1>
</ cent er >
<t abl e wi dt h=" 90%" >
<t r >
<t d hei ght =" 25%" col span=" 2" >
<t i l es: i nser t at t r i but e=" encabezado" / >
</ t d>
</ t r >
<t r >
<t d>
<t i l es: i nser t at t r i but e=" menu" / >
</ t d>
<t d>
<t i l es: i nser t at t r i but e=" cuer po" / >
</ t d>
</ t r >
</ t abl e>
</ body>
</ ht ml >
7.2.2 Creacin de piezas de contenido
Las piezas de contenido representan las porciones de cdigo XHTML/J SP
que sustituirn a los elementos <tiles:insert>durante la creacin de las pginas de
aplicacin.
206 STRUTS RA-MA

Por lo general, estos bloques de contenido se almacenan en archivos .jsp y,
dado que su contenido formar parte de las pginas finales, pueden incluir tanto
cdigo XHTML/J SP estndar como acciones de Struts.
Al igual que sucede con las pginas maestras, para evitar que puedan ser
directamente accesibles desde el cliente, estos archivos deberan estar situados en
el directorio WEB-INF de la aplicacin.
Los siguientes ejemplos representan las pginas que podran ser utilizadas
como contenidos para las zonas definidas en la plantilla anterior:
titulo.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<di v al i gn=" cent er " st yl e=" backgr ound- col or : aqua" >
<h1>Apl i caci n de ej empl o</ h1>
</ cent er >
menu.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- ht ml "
pr ef i x=" ht ml " %>
<t abl e>
<t r >
<t d>
<a hr ef =" " >opci n 1</ a><br / >
</ t d>
</ t r >
<t r >
<t d>
<a hr ef =" " >opci n 2</ a><br / >
</ t d>
</ t r >
<t r >
<t d>
<a hr ef =" " >opci n 3</ a><br / >
</ t d>
</ t r >
<t r >
RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 207

<t d>
<a hr ef =" " >opci n 4</ a><br / >
</ t d>
</ t r >
</ t abl e>
body1.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<h1>Cont eni do pr i mer o</ h1>
<h3>Est e es el cuer po de l a pgi na 1</ h3>
body2.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<h1>Cont eni do segundo</ h1>
<h3>Est e es el cuer po de l a pgi na 2</ h3>
7.2.3 Creacin de las pginas de aplicacin
Una vez que se dispone de la plantilla y de las piezas de contenido, crear
las pginas de la aplicacin resulta una tarea tremendamente sencilla. Para ello tan
slo ser necesario declarar al principio de la pgina la plantilla que se va a utilizar
e indicar a continuacin las piezas que queremos situar en cada zona de contenido.
7.2.4 Declaracin de la plantilla
La declaracin de la plantilla se lleva a cabo mediante la accin
<tiles:insert>, utilizando en este caso el atributo page de la accin para indicar la
direccin relativa de la pgina maestra. Por ejemplo, suponiendo que la plantilla se
encuentra definida en un archivo llamado base.jsp que est situado en el directorio
WEB-INF, la declaracin de la plantilla en la pgina de aplicacin sera:
<tiles:insert page="/WEB-INF/base.jsp">
<!--Aqu referencias a pginas de contenido-->
</tiles:insert>
208 STRUTS RA-MA

7.2.5 Inclusin de pginas de contenido
En el interior de insert debemos indicar las piezas que queremos incluir en
cada zona de contenido especificada en la plantilla. Esta sencilla operacin es
realizada mediante la accin <tiles:put>, cuya configuracin se realiza a travs de
sus dos atributos:
name. Nombre de la zona de contenido a la que hace referencia.
ste deber coincidir con alguno de los valores de los atributos
attribute o name definidos en las acciones <tiles:insert> y
<tiles:getAsString>de la plantilla.
value. Contenido a incluir en la zona especificada en name. En el
caso de zonas definidas mediante <tiles:insert>, value especificar
la URL relativa de la pgina de contenido, mientras que en el caso
de <tiles:getAsString>contendr la cadena de texto por la que ser
sustituido el elemento.
En el ejemplo que estamos analizando, las pginas de aplicacin indicadas
en la figura 33 se generarn de la forma que se indica en los siguientes listados:
pagina1.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<!--declaracin de plantilla-->
<t i l es: i nser t page=" / WEB- I NF/ pl ant i l l as/ pl ant i l l a. j sp" >
<t i l es: put name=" t i t ul o"
val ue=" Pagi na 1" / >
<t i l es: put name=" encabezado"
val ue=" / WEB- I NF/ pl ant i l l as/ t i t ul o. j sp" / >
<t i l es: put name=" menu"
val ue=" / WEB- I NF/ pl ant i l l as/ menu. j sp" / >
<t i l es: put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ body1. j sp" / >
</ t i l es: i nser t >


RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 209

pagina2.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>

<t i l es: i nser t page=" / WEB- I NF/ pl ant i l l as/ pl ant i l l a. j sp" >
<t i l es: put name=" t i t ul o" val ue=" Pagi na 2" / >
<t i l es: put name=" encabezado"
val ue=" / WEB- I NF/ pl ant i l l as/ t i t ul o. j sp" / >
<t i l es: put name=" menu"
val ue=" / WEB- I NF/ pl ant i l l as/ menu. j sp" / >
<t i l es: put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ body2. j sp" / >
</ t i l es: i nser t >
7.3 DEFINICIONES
El mecanismo de utilizacin de plantillas que se acaba de analizar nos
permite reutilizar cdigo en las aplicaciones, adems de proporcionarnos gran
flexibilidad a la hora de crear las pginas finales de la aplicacin. Sin embargo, es
en la creacin de estas pginas finales donde observamos tambin la aparicin de
numerosos elementos repetitivos, por ejemplo, en el cdigo de las pginas
anteriores vemos cmo el elemento <tiles:put>utilizado en la definicin de las
zonas de encabezado y men es idntico en ambas pginas.
Otro defecto que presenta el sistema anterior es el hecho de que cualquier
cambio en la ubicacin de alguno de estos archivos de contenido implicar tener
que actualizar todas las pginas de la aplicacin donde se haga referencia a stos,
lo que puede resultar en una importante fuente de errores.
La solucin que propone Struts para estos problemas consiste en la
utilizacin de definiciones. Una definicin, como su nombre indica, define una
manera de distribuir las piezas de contenido en una plantilla, de modo que a la hora
de crear una definicin con contenido similar a otra ya existente no sea necesario
volver a definir de nuevo los mismos elementos ya establecidos en la anterior
definicin, sino que bastar con que la nueva definicin herede a la primera y
redefina nicamente aquellas zonas cuyo contenido es diferente al indicado en la
definicin padre.
210 STRUTS RA-MA

7.3.1 Creacin de una definicin
Antes de crear una definicin debemos disponer de una plantilla y una serie
de pginas de contenido. El desarrollo de estos elementos se lleva a cabo tal y
como explicamos en la seccin anterior.
En cuanto a las definiciones, stas se crean en un nuevo archivo de
configuracin llamado tiles-defs.xml, cuya ubicacin deber estar indicada en el
elemento <plug-in>definido en struts-config.xml, tal y como se indic al comienzo
del Captulo. Lo habitual es que tiles-defs.xml se site en el directorio WEB-INF
de la aplicacin.
La estructura de este archivo es la que se muestra a continuacin:
<! DOCTYPE t i l es- def i ni t i ons PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD Ti l es
Conf i gur at i on 1. 1/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/
t i l es- conf i g_1_1. dt d" >

<t i l es- def i ni t i ons>
:
</ t i l es- def i ni t i ons>
Como vemos, existe un elemento <tiles-definitions>dentro del cual se
incluirn todas las definiciones que se vayan a utilizar en la aplicacin, cada una de
ellas en su propio elemento <definition>.
7.3.1.1 DEFINICIONES BASE
Una definicin base es aqulla que define explcitamente la distribucin de
los contenidos de cada zona indicada en la plantilla, sin heredar ninguna otra
definicin existente.
En este tipo de definicin habr que especificar los siguientes atributos del
elemento <definition>:
name. Nombre asignado a la definicin.
path. URL relativa de la pgina maestra que contiene la plantilla a
partir de la que se va a crear la definicin.
RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 211

Para indicar el contenido de cada zona se utilizar el subelemento <put>de
<definition>, el cual dispone a su vez de los atributos:
name. Nombre de la zona para la que se va a indicar el contenido.
value. En el caso de las zonas definidas con <tiles:insert>este
atributo indicar la URL relativa de la pgina de contenido,
mientras que para las zonas <tiles:getAsString> contendr la
cadena de texto equivalente.
7.3.1.2 DEFINICIONES DERIVADAS
A la hora de crear una definicin derivada de otra debemos especificar en
el atributo extends del elemento <definition>el nombre de la definicin base. De
esta manera, el elemento heredar todas las definiciones <put>especificadas en el
<definition>padre. Si queremos redefinir el contenido de cualquiera de las zonas
utilizaremos nuevamente el elemento <put>.
El siguiente listado corresponde a las tres definiciones que utilizaremos
para implementar nuevamente las pginas del ejemplo presentado en la seccin
anterior, la primera de ellas corresponde a la definicin base en la que se indican
los elementos comunes a las dos pginas, mientras que las otras dos definiciones
heredarn a la base, indicndose en ellas los elementos propios de cada pgina:
<t i l es- def i ni t i ons>
<def i ni t i on name=" . pr i nci pal "
pat h=" / WEB- I NF/ pl ant i l l as/ pl ant i l l a. j sp" >
<put name=" t i t ul o" val ue=" " / >
<put name=" encabezado"
val ue=" / WEB- I NF/ pl ant i l l as/ t i t ul o. j sp" / >
<put name=" menu"
val ue=" / WEB- I NF/ pl ant i l l as/ menu. j sp" / >
<put name=" cuer po" val ue=" " / >
</ def i ni t i on>
<def i ni t i on name=" . par apagi na1" ext ends=" . pr i nci pal " >
<put name=" t i t ul o" val ue=" Pagi na 1" / >
<put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ body1. j sp" / >
</ def i ni t i on>
<def i ni t i on name=" . par apagi na2" ext ends=" . pr i nci pal " >
<put name=" t i t ul o" val ue=" Pagi na 2" / >


212 STRUTS RA-MA

<put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ body2. j sp" / >
</ def i ni t i on>
</ t i l es- def i ni t i ons>
7.3.2 Pginas de aplicacin
Una vez creadas las definiciones, la implementacin de las pginas de
aplicacin resulta tremendamente sencilla; utilizando el atributo definition del
elemento <tiles:insert> indicaremos el nombre de la definicin que queremos
aplicar a cada pgina. El siguiente listado indica como quedara la implementacin
de las pginas pagina1.jsp y pagina2.jsp del ejemplo:
pagina1.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b
ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<t i l es: i nser t def i ni t i on=" . par apagi na1" / >
pagina2.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b
ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<t i l es: i nser t def i ni t i on=" . par apagi na2" / >
PRCTICA 7.1. APLICACIN PARA EL ENVO Y
VISUALIZACIN DE MENSAJES
Descripcin
Se trata de realizar una nueva versin de la aplicacin desarrollada en la
prctica 5.2 para envo y visualizacin de mensajes, utilizando plantillas para la
creacin de un aspecto comn en todas la pgina de la aplicacin y definiciones
para la reutilizacin de elementos comunes en las vistas.

RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 213

El nuevo aspecto de las pginas de la aplicacin es el que se muestra en la
figura 34.










Fig. 34. Pginas de la aplicacin
Desarrollo
En una pgina maestra (master.jsp) se crear la estructura de las pginas de
la aplicacin, la cual estar formada por una zona superior, un men lateral
izquierdo y un cuerpo central.
El men ser comn a todas las pginas y estar formado por una pgina
J SP (menu.jsp) con los dos enlaces que se muestran en la figura. La zona superior
estar formada por un elemento de texto, mientras que el cuerpo ser ocupado por
una pgina J SP que ser diferente para cada pgina. Tanto la pgina maestra como
las pginas de contenido se colocarn en un directorio interno en WEB-INF.
En el archivo tiles-defs.xml se indicarn las definiciones. Habr una
principal de la que hereden otras cinco, una para cada pgina. De esta manera, las
pginas de la aplicacin slo incluirn una referencia a la definicin a aplicar.

214 STRUTS RA-MA

Listado
Mostraremos nicamente las pginas J SP y los archivos de configuracin,
puesto que las clases controlador y de negocio no sufren ninguna alteracin
respecto a la versin presentada en la prctica 5.2.
struts-config.xml
En fondo sombreado se muestran las modificaciones realizadas para
apuntar a las nuevas pginas, as como los nuevos elementos incluidos para
permitir la utilizacin de tiles:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE st r ut s- conf i g PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s
Conf i gur at i on 1. 2/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/ st r ut s-
conf i g_1_2. dt d" >
<st r ut s- conf i g>
<f or m- beans>
<f or m- bean name=" Mensaj eFor m"
t ype=" j avabeans. Mensaj eFor m" / >
</ f or m- beans>
<gl obal - f or war ds>
<f or war d name=" pr evi oenvi o"
pat h=" / pagi naenvi o. j sp" / >
<f or war d name=" pr evi ol ect ur a"
pat h=" / pagi nasol i ci t ud. j sp" / >
<f or war d name=" i ni ci o"
pat h=" / pagi nai ni ci o. j sp" / >
</ gl obal - f or war ds>
<act i on- mappi ngs>
<act i on name=" Mensaj eFor m" pat h=" / gr abar "
scope=" r equest " t ype=" ser vl et s. Envi ar Act i on" >
<f or war d name=" gr abado"
pat h=" / pagi nai ni ci o. j sp" / >
</ act i on>
<act i on pat h=" / most r ar "
t ype=" ser vl et s. Recuper ar Act i on" >
<f or war d name=" vi sual i za"
pat h=" / pagi namuest r a. j sp" / >
<f or war d name=" si nmensaj es"
RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 215

pat h=" / pagi nanomensaj es. j sp" / >
</ act i on>
</ act i on- mappi ngs>
<cont r ol l er pr ocessor Cl ass=" or g. apache. st r ut s.
t i l es. Ti l esRequest Pr ocessor " / >
<pl ug- i n cl assName=" or g. apache. st r ut s.
t i l es. Ti l esPl ugi n" >
<set - pr oper t y pr oper t y=" def i ni t i ons- conf i g"
val ue=" / WEB- I NF/ t i l es- def s. xml " / >
<set - pr oper t y pr oper t y=" modul eAwar e"
val ue=" t r ue" / >
</ pl ug- i n>
</ st r ut s- conf i g>
tiles-defs.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>

<! DOCTYPE t i l es- def i ni t i ons PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD Ti l es
Conf i gur at i on 1. 1/ / EN"
" ht t p: / / j akar t a. apache. or g/ st r ut s/ dt ds/ t i l es-
conf i g_1_1. dt d" >

<t i l es- def i ni t i ons>
<def i ni t i on name=" . pr i nci pal "
pat h=" / WEB- I NF/ pl ant i l l as/ mast er . j sp" >
<put name=" t i t ul o" val ue=" Apl i caci n Web par a env o y
r ecepci n de mensaj es" / >
<put name=" menu"
val ue=" / WEB- I NF/ pl ant i l l as/ menu. j sp" / >
<put name=" cuer po" val ue=" " / >
</ def i ni t i on>
<def i ni t i on name=" . i ni ci o" ext ends=" . pr i nci pal " >
<put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ bodyi ni ci o. j sp" / >
</ def i ni t i on>
<def i ni t i on name=" . sol i ci t ud" ext ends=" . pr i nci pal " >
<put name=" t i t ul o" val ue=" Dat os del dest i nat ar i o" / >
<put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ bodysol i ci t ud. j sp" / >
</ def i ni t i on>
216 STRUTS RA-MA

<def i ni t i on name=" . envi o" ext ends=" . pr i nci pal " >
<put name=" t i t ul o" val ue=" Gener aci n de mensaj es" / >
<put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ bodyenvi o. j sp" / >
</ def i ni t i on>
<def i ni t i on name=" . muest r a" ext ends=" . pr i nci pal " >
<put name=" t i t ul o" val ue=" Li st ado de mensaj es" / >
<put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ bodymuest r a. j sp" / >
</ def i ni t i on>
<def i ni t i on name=" . nomensaj es" ext ends=" . pr i nci pal " >
<put name=" t i t ul o" val ue=" Avi so" / >
<put name=" cuer po"
val ue=" / WEB- I NF/ pl ant i l l as/ bodynomensaj es. j sp" / >
</ def i ni t i on>
</ t i l es- def i ni t i ons>
Plantillas y pginas de contenido
master.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- l ogi c"
pr ef i x=" l ogi c" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- bean"
pr ef i x=" bean" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- ht ml "
pr ef i x=" ht ml " %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml : ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ;
char set =UTF- 8" >
<t i t l e><t i l es: get AsSt r i ng name=" t i t ul o" / ></ t i t l e>
</ head>


RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 217

<body>
<t abl e wi dt h=" 100%" >
<t r val i gn=" cent er " >
<t d hei ght =" 25%" al i gn=" cent er "
col span=" 2" >
<h1>
<t i l es: get AsSt r i ng name=" t i t ul o" / >
</ h1>
</ t d>
</ t r >
<t r >
<t d wi dt h=" 100px" >
<t i l es: i nser t at t r i but e=" menu" / >
</ t d>
<t d>
<t i l es: i nser t at t r i but e=" cuer po" / >
</ t d>
</ t r >
</ t abl e>
</ body>
</ ht ml : ht ml >
menu.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<cent er >
<br / ><br / >
<ht ml : l i nk f or war d=" pr evi oenvi o" >
Envi ar mensaj e
</ ht ml : l i nk>
<br / ><br / >
<ht ml : l i nk f or war d=" pr evi ol ect ur a" >
Leer mensaj es
</ ht ml : l i nk>
</ cent er >


218 STRUTS RA-MA

bodyinicio.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<cent er >
<h3>Bi enveni do a l a apl i caci n de env o y
r ecpci n de mensaj es</ h3>
</ cent er >
bodyenvio.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>

<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<cent er >
<ht ml : f or mact i on=" / gr abar " met hod=" POST" >
<br / ><br / >
<b>Dat os del mensaj e: </ b><br / ><br / >
<t abl e>
<t r >
<t d>I nt r oduzca dest i nat ar i o: </ t d>
<t d>
<ht ml : t ext pr oper t y=" dest i no" / >
</ t d>
</ t r >
<t r >
<t d>I nt r oduzca r emi t ent e: </ t d>
<t d>
<ht ml : t ext pr oper t y=" r emi t e" / >
</ t d>
</ t r >
<t r >
<t d>I nt r oduzca t ext o : </ t d>
<t d>
<ht ml : t ext ar ea pr oper t y=" t ext o" >
</ ht ml : t ext ar ea>
</ t d>
</ t r >


RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 219

<t r >
<t d col span=" 2" ><ht ml : submi t val ue=" Envi ar " / ></ t d>
</ t r >
</ t abl e>
</ ht ml : f or m>
</ cent er >
</ body>
bodymuestra.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j avabeans. *, j ava. ut i l . *" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- l ogi c
pr ef i x=" l ogi c" %>

<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- ht ml
pr ef i x=" ht ml " %>
<cent er >
<bean: par amet er i d=" nombr e" name=" nombr e" / >
<h3>
Mensaj es par a <bean: wr i t e name=" nombr e" / >
</ h3>
<t abl e bor der =" 1" >
<t r >
<t h>Remi t ent e</ t h>
<t h>Mensaj e</ t h>
</ t r >
<l ogi c: i t er at e i d=" mensaj e" name=" mensaj es"
scope=" r equest " >
<t r >
<t d>
<bean: wr i t e name=" mensaj e"
pr oper t y=" r emi t e" / >
</ t d>
<t d>
<bean: wr i t e name=" mensaj e"
pr oper t y=" t ext o" / >
</ t d>
</ t r >
220 STRUTS RA-MA

</ l ogi c: i t er at e>
</ t abl e>
<br / ><br / >
<ht ml : l i nk f or war d=" i ni ci o" >I ni ci o</ ht ml : l i nk>
</ cent er >
bodysolicitud.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<cent er >
<br / ><br / >
<f or mact i on=" most r ar . do" met hod=" post " >
I nt r oduzca su nombr e:
<i nput t ype=" t ext " name=" nombr e" ><br ><br >
<i nput t ype=" submi t " val ue=" Most r ar mensaj es" >
</ f or m>
</ cent er >
bodynomensajes.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@page i mpor t =" j avabeans. *, j ava. ut i l . *" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- bean
pr ef i x=" bean" %>
<%@t agl i b ur i =" ht t p: / / st r ut s. apache. or g/ t ags- ht ml "
pr ef i x=" ht ml " %>
<bean: par amet er i d=" nombr e" name=" nombr e" / >
<cent er >
<h2>
Lo si ent o, <bean: wr i t e name=" nombr e" / > no t i ene mensaj es
</ h2>
<br / ><br / ><br / ><br / >
<ht ml : l i nk f or war d=" i ni ci o" >
I ni ci o
</ ht ml : l i nk>
</ cent er >


RA-MA CAPTULO 7. UTILIZACIN DE PLANTILLAS 221

Pginas de aplicacin
paginainicio.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<t i l es: i nser t def i ni t i on=" . i ni ci o" / >
paginaenvio.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<t i l es: i nser t def i ni t i on=" . envi o" / >
paginamuestra.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<t i l es: i nser t def i ni t i on=" . muest r a" / >
paginasolicitud.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<t i l es: i nser t def i ni t i on=" . sol i ci t ud" / >
paginanomensajes.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b ur i =ht t p: / / st r ut s. apache. or g/ t ags- t i l es
pr ef i x=" t i l es" %>
<t i l es: i nser t def i ni t i on=" . nomensaj es" / >


8Captulo 8
STRUTS 2
Las cada vez ms exigentes demandas de las aplicaciones Web modernas
han llevado al equipo de desarrollo de Struts, en su afn de mejorar continuamente
las prestaciones del framework, a replantear la estructura y composicin del
mismo, adoptando un nuevo enfoque que resulte ms flexible y sencillo de utilizar.
En esta lnea nace Struts 2.
Ms que una nueva versin de Struts, Struts 2 es realmente la fusin de dos
frameworks: por un lado el clsico Struts (conocido tambin a partir de ahora como
Struts 1) con nuevas capacidades aadidas, y por otro WebWork (o mejor dicho
WebWork 2, la versin actualizada y mejorada de ste), un framework desarrollado
por OpenSymphony que proporciona un fuerte desacoplamiento entre las capas de
la aplicacin.
El resultado es un producto que integra las capacidades de ambos
frameworks, lo que sin duda hace de Struts 2 el marco de trabajo ms atractivo y
potente para la creacin de aplicaciones Web con arquitectura MVC.
Lo anterior no significa que Struts 1 haya entrado en vas de desaparicin,
ni mucho menos. Struts 1 es un framework muy consolidado, integrado en la
mayora de los entornos de desarrollo ms importantes y utilizado por una
amplsima comunidad de desarrolladores, mientras que Struts 2 tiene que madurar
mucho an, si bien tiene un gran futuro por delante.

224 STRUTS RA-MA

8.1 COMPONENTES DE STRUTS 2
Como decimos, Struts 2 sigue siendo fiel a la arquitectura MVC, si bien los
roles que desempean algunos de los componentes tradicionales cambian con
respecto a las versiones 1.x.
La figura 35 muestra los principales componentes de Struts 2, su ubicacin
dentro de las distintas capas de la aplicacin y la interaccin entre los mismos.











Fig. 35. Componentes y capas de una aplicacin Struts 2
A continuacin estudiaremos el funcionamiento y principales
caractersticas de estos componentes, analizando su comportamiento a lo largo del
ciclo de vida de la peticin desde que sta llega al Controlador hasta que se enva la
respuesta al cliente.
8.1.1 FilterDispatcher
Este componente representa el punto de entrada a la aplicacin,
dirigindose a l todas las peticiones que llegan desde el cliente. FilterDispatcher
hace en Struts 2 las veces de ActionServlet en Struts 1, analizando la peticin
FilterDispatcher
(JSP,
Velocity,
Frameker)
Clases de
negocio
struts.xml
Action1
Action2
Controlador
Interceptor1
Interceptor2
:
Interceptorn
Modelo
Vista
ActionProxy
ActionInvocation
RA-MA CAPTULO 8. STRUTS 2 225

recibida y determinando con el apoyo de otros objetos auxiliares y de la
informacin almacenada en el archivo de configuracin struts.xml el tipo de accin
a ejecutar.
FilterDispatcher forma parte del API de Struts 2, concretamente, se incluye
dentro del paquete org.apache.struts2.dispatcher.y, como se deduce de su propio
nombre, es implementado mediante un filtro, por lo que debe ser registrado en el
archivo web.xml de la aplicacin tal y como se indica en el siguiente listado:
:
<f i l t er >
<f i l t er - name>st r ut s2</ f i l t er - name>
<f i l t er - cl ass>or g. apache. st r ut s2.
di spat cher . Fi l t er Di spat cher
</ f i l t er - cl ass>
</ f i l t er >

<f i l t er - mappi ng>
<f i l t er - name>st r ut s2</ f i l t er - name>
<ur l - pat t er n>/ *</ ur l - pat t er n>
</ f i l t er - mappi ng>
:
8.1.2 Interceptores
Una vez determinada la accin a ejecutar, FilterDispatcher pasa el control
de la peticin a un objeto intermediario de tipo ActionProxy, ste crea un objeto
ActionInvocation en el que almacena la informacin de la peticin entrante,
pasando a continuacin el control de la misma a los interceptores.
Los interceptores constituyen una cadena de objetos que realizan una serie
de tareas de pre-procesamiento previas antes de ejecutar la accin, como por
ejemplo la validacin de datos de usuario, rellenado de objetos con los campos de
un formulario, etc., as como un post-procesamiento de los resultados una vez que
stos ha sido generados por las clases de accin.
El funcionamiento de los interceptores es muy similar a los filtros servlet,
ejecutndose en cadena al recibir la peticin, en el orden indicado en el archivo de
configuracin struts.xml y en orden inverso durante el envo de la respuesta al
cliente.
226 STRUTS RA-MA

El API de Struts incorpora un gran nmero de interceptores, pudiendo
decidir el programador cules de ellos deben ejecutarse para cada accin
simplemente indicndolo en el archivo de configuracin struts.xml. Algunos de
estos interceptores proporcionan a las clases de accin acceso a los distintos
objetos del API Servlet, a fin de que stas puedan controlar los datos manejados en
la aplicacin.
Como veremos ms adelante, un programador tambin puede implementar
sus propios interceptores para realizar algn tipo de pre-procesamiento o post-
procesamiento personalizado que no est contemplado por ninguno de los
interceptores del API. Para este propsito Struts 2 proporciona la interfaz
Interceptor.
8.1.3 Action
Como sucede en Struts 1, los objetos Action se encargan del procesamiento
de las peticiones del cliente. Sin embargo, en Struts 2 este tipo de objetos presenta
notables diferencias respecto a las versiones anteriores; analizaremos las ms
significativas:
Los objetos Action forman parte del modelo. Esto se puede
apreciar en el esquema que hemos presentado en la figura 35.
Aunque por regla general, al igual que suceda en Struts 1.x, la
lgica de negocio se suele aislar en clases independientes o EJ B,
incluyndose en las clases de accin las llamadas a los mtodos
expuestos por estos objetos.
Implementacin como clases POJO. La principal caracterstica
de las clases de accin de Struts 2 es que no tienen que heredar ni
implementar ninguna clase o interfaz del API. Son clases
estndares J ava, comnmente conocidas tambin como Plain Old
Java Objects (POJO) y cuyo nico requerimiento es tener que
proporcionar un mtodo, que por convenio es llamado execute() al
igual que las clases de accin utilizadas en versiones anteriores del
framework, en el que se debern incluir las instrucciones a ejecutar
para el procesamiento de la accin. Este mtodo ser invocado por
el ltimo interceptor de la cadena.
Inclusin de mtodos set/get. Otra de las caractersticas de Struts
2 es que se ha eliminado la utilizacin de clases de tipo
ActionForm para la encapsulacin de datos procedentes de un
formulario cliente. En su defecto, estos datos son capturados por
RA-MA CAPTULO 8. STRUTS 2 227

el propio objeto de accin invocado desde el Controlador,
operacin que es realizada con ayuda de uno de los interceptores
incluidos en el API de Struts 2, resultando as transparente para el
programador. Lo nico que en este sentido habr que codificar en
las clases de accin (adems del mtodo execute() para el
tratamiento de la peticin) sern los datos miembro para el
almacenamiento de los campos con sus correspondientes mtodos
set/get, de forma similar a como se haca en las clases ActionForm
de Struts 1.
Este nuevo sistema permite simplificar doblemente el desarrollo de
la aplicacin, ya que por un lado se reduce el nmero de tipos
distintos de clases a implementar y, por otro, se dispone
directamente de los datos en la misma clase donde van a ser
manipulados.
En caso de que queramos encapsular los datos en objetos para
facilitar su transporte entre las clases Action y los componentes
que encapsulan la lgica de negocio, se utilizarn J avaBeans
estndares.
8.1.4 Libreras de acciones
Como en Struts 1, Struts 2 incluye un amplio conjunto de acciones o tags
que facilitan la creacin de las vistas. Estas acciones se incluyen en la librera de
uri asociada /struts-tags.
Como novedad respecto a las versiones anteriores, estas acciones pueden
utilizarse no slo en la construccin de pginas J SP, tambin con otras tecnologas
para la creacin de vistas como son las plantillas velocity o freemaker.
Adems de incluir una gran variedad de componentes grficos y elementos
de control de flujo, esta librera proporciona acciones que permiten acceder
directamente desde la vista a la accin que se acaba de ejecutar, facilitndose
as el acceso a los datos generados por el modelo.
8.1.5 Archivo de configuracin struts.xml
Las aplicaciones Struts 2 utilizan un archivo de configuracin llamado
struts.xml en el que se registran y configuran los distintos componentes de la
aplicacin, realizndose estas tareas de una manera ms simple que en struts-
config.xml de Struts 1.
228 STRUTS RA-MA

Entre otros elementos, en struts.xml debemos registrar los Action, con sus
correspondientes reglas de navegacin, y los interceptores.
Struts 2 soporta adems la herencia de archivos de configuracin, lo que
se traduce en poder utilizar una serie de configuraciones por defecto en las
aplicaciones sin tener que reescribirlas de nuevo en cada struts.xml particular.
La figura 36 nos muestra la estructura bsica de un archivo struts.xml. Este
fichero debe residir en un directorio que est incluido en el classpath de la
aplicacin, habitualmente raiz_aplicacion\WEB-INF\classes.











Fig. 36. Archivo de configuracin struts.xml
8.1.5.1 PAQUETES
Cada configuracin definida dentro de struts.xml se incluye dentro de un
paquete, el cual viene definido por el elemento <package>. Los paquetes permiten
agrupar un conjunto de elementos (habitualmente acciones) que comparten una
serie de atributos de configuracin comunes.
Un elemento <package>puede incluir los siguientes atributos:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE strutsPUBLIC
"-//Apache SoftwareFoundation//DTDStrutsConfiguration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package....>
<interceptors>
<!--definicin de interceptores personalizados-->
</interceptors>
<action ...>
<!--configuracin de elementos para la accin-->
</action>
:
</package>
:
</struts>
RA-MA CAPTULO 8. STRUTS 2 229

name. Nombre o identificador asociado y que debe ser nico para
cada paquete.
namespace. Proporciona un mapeo desde la URL al paquete. Por
ejemplo, si al atributo namespace de un determinado paquete se le
ha asignado el valor packexample, la URL para acceder a las
acciones definidas en el interior del mismo ser:
raiz_aplicacion\packexample\nombreaccion.action.
extends. Nombre del paquete heredado. Como hemos indicado
anteriormente, Struts 2 permite la herencia entre archivos de
configuracin, concretamente, la herencia de paquetes.
8.1.5.2 HERENCIA DE PAQUETES
Struts 2 proporciona un archivo de configuracin por defecto llamado
struts-default.xml, en el que se incluye un paquete de nombre struts-default con
una serie de configuraciones predefinidas disponibles para ser utilizadas en
cualquier aplicacin. Entre otras cosas, este paquete configura una serie de
interceptores predefinidos de Struts 2, por lo que si queremos disponer de la
funcionalidad de los mismos en nuestra aplicacin, ser conveniente crear paquetes
que hereden a ste:
<package name=" paquet e1"
namespace=" packexampl e"
extends="struts-default">
:
</ package>
A modo de ejemplo, en el siguiente listado se muestra el contenido del
archivo de configuracin por defecto de Struts 2 struts-default.xml, el cual se
encuentra incluido en la librera struts2-core-2.0.11.jar suministrada con el paquete
de distribucin de Struts 2:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! - -
/ *
* $I d: st r ut s- def aul t . xml 559615 2007- 07- 25 21: 25: 25Z apet r el l i $
*
* Li censed t o t he Apache Sof t war e Foundat i on ( ASF) under one
* or mor e cont r i but or l i cense agr eement s. See t he NOTI CE f i l e
* di st r i but ed wi t h t hi s wor k f or addi t i onal i nf or mat i on
* r egar di ng copyr i ght owner shi p. The ASF l i censes t hi s f i l e
* t o you under t he Apache Li cense, Ver si on 2. 0 ( t he
* " Li cense" ) ; you may not use t hi s f i l e except i n compl i ance
* wi t h t he Li cense. You may obt ai n a copy of t he Li cense at
*
230 STRUTS RA-MA

* ht t p: / / www. apache. or g/ l i censes/ LI CENSE- 2. 0
*
* Unl ess r equi r ed by appl i cabl e l aw or agr eed t o i n wr i t i ng,
* sof t war e di st r i but ed under t he Li cense i s di st r i but ed on an
* " AS I S" BASI S, WI THOUT WARRANTI ES OR CONDI TI ONS OF ANY
* KI ND, ei t her expr ess or i mpl i ed. See t he Li cense f or t he
* speci f i c l anguage gover ni ng per mi ssi ons and l i mi t at i ons
* under t he Li cense.
*/
- - >

<! DOCTYPE st r ut s PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s Conf i gur at i on
2. 0/ / EN"
" ht t p: / / st r ut s. apache. or g/ dt ds/ st r ut s- 2. 0. dt d" >

<st r ut s>
<bean cl ass=" com. opensymphony. xwor k2. Obj ect Fact or y"
name=" xwor k" / >
<bean t ype=" com. opensymphony. xwor k2. Obj ect Fact or y" name=" st r ut s"
cl ass=" or g. apache. st r ut s2. i mpl . St r ut sObj ect Fact or y" / >

<bean t ype=" com. opensymphony. xwor k2. Act i onPr oxyFact or y"
name=" xwor k"
cl ass=" com. opensymphony. xwor k2. Def aul t Act i onPr oxyFact or y" / >
<bean t ype=" com. opensymphony. xwor k2. Act i onPr oxyFact or y"
name=" st r ut s"
cl ass=" or g. apache. st r ut s2. i mpl . St r ut sAct i onPr oxyFact or y" / >

<bean t ype=" com. opensymphony. xwor k2. ut i l . Obj ect TypeDet er mi ner "
name=" t i ger "
cl ass=" com. opensymphony. xwor k2. ut i l . Gener i csObj ect TypeDet er mi ner " / >
<bean t ype=" com. opensymphony. xwor k2. ut i l . Obj ect TypeDet er mi ner "
name=" not i ger "
cl ass=" com. opensymphony. xwor k2. ut i l . Def aul t Obj ect TypeDet er mi ner " / >
<bean t ype=" com. opensymphony. xwor k2. ut i l . Obj ect TypeDet er mi ner "
name=" st r ut s"
cl ass=" com. opensymphony. xwor k2. ut i l . Def aul t Obj ect TypeDet er mi ner " / >

<bean t ype=" or g. apache. st r ut s2. di spat cher . mapper . Act i onMapper "
name=" st r ut s"
cl ass=" or g. apache. st r ut s2. di spat cher . mapper . Def aul t Act i onMapper " / >
<bean t ype=" or g. apache. st r ut s2. di spat cher . mapper . Act i onMapper "
name=" composi t e"
cl ass=" or g. apache. st r ut s2. di spat cher . mapper . Composi t eAct i onMapper "
/ >
<bean t ype=" or g. apache. st r ut s2. di spat cher . mapper . Act i onMapper "
name=" r est f ul "
cl ass=" or g. apache. st r ut s2. di spat cher . mapper . Rest f ul Act i onMapper " / >
<bean t ype=" or g. apache. st r ut s2. di spat cher . mapper . Act i onMapper "
name=" r est f ul 2"
cl ass=" or g. apache. st r ut s2. di spat cher . mapper . Rest f ul 2Act i onMapper " / >

<bean
t ype=" or g. apache. st r ut s2. di spat cher . mul t i par t . Mul t i Par t Request "
name=" st r ut s"
cl ass=" or g. apache. st r ut s2. di spat cher . mul t i par t . J akar t aMul t i Par t Reque
st " scope=" def aul t " opt i onal =" t r ue" / >
RA-MA CAPTULO 8. STRUTS 2 231

<bean
t ype=" or g. apache. st r ut s2. di spat cher . mul t i par t . Mul t i Par t Request "
name=" j akar t a"
cl ass=" or g. apache. st r ut s2. di spat cher . mul t i par t . J akar t aMul t i Par t Reque
st " scope=" def aul t " opt i onal =" t r ue" / >

<bean t ype=" or g. apache. st r ut s2. vi ews. TagLi br ar y" name=" s"
cl ass=" or g. apache. st r ut s2. vi ews. Def aul t TagLi br ar y" / >

<bean
cl ass=" or g. apache. st r ut s2. vi ews. f r eemar ker . Fr eemar ker Manager "
name=" st r ut s" opt i onal =" t r ue" / >
<bean cl ass=" or g. apache. st r ut s2. vi ews. vel oci t y. Vel oci t yManager "
name=" st r ut s" opt i onal =" t r ue" / >

<bean
cl ass=" or g. apache. st r ut s2. component s. t empl at e. Templ at eEngi neManager "
/ >
<bean
t ype=" or g. apache. st r ut s2. component s. t empl at e. Templ at eEngi ne"
name=" f t l "
cl ass=" or g. apache. st r ut s2. component s. t empl at e. Fr eemar ker Templ at eEngi
ne" / >
<bean
t ype=" or g. apache. st r ut s2. component s. t empl at e. Templ at eEngi ne"
name=" vm"
cl ass=" or g. apache. st r ut s2. component s. t empl at e. Vel oci t yTempl at eEngi ne
" / >
<bean
t ype=" or g. apache. st r ut s2. component s. t empl at e. Templ at eEngi ne"
name=" j sp"
cl ass=" or g. apache. st r ut s2. component s. t empl at e. J spTempl at eEngi ne" / >

<bean t ype=" com. opensymphony. xwor k2. ut i l . XWor kConver t er "
name=" xwor k1" cl ass=" com. opensymphony. xwor k2. ut i l . XWor kConver t er " / >
<bean t ype=" com. opensymphony. xwor k2. ut i l . XWor kConver t er "
name=" st r ut s"
cl ass=" com. opensymphony. xwor k2. ut i l . Annot at i onXWor kConver t er " / >
<bean t ype=" com. opensymphony. xwor k2. Text Pr ovi der " name=" xwor k1"
cl ass=" com. opensymphony. xwor k2. Text Pr ovi der Suppor t " / >
<bean t ype=" com. opensymphony. xwor k2. Text Pr ovi der " name=" st r ut s"
cl ass=" com. opensymphony. xwor k2. Text Pr ovi der Suppor t " / >

<! - - Onl y have st at i c i nj ect i ons - - >
<bean cl ass=" com. opensymphony. xwor k2. Obj ect Fact or y"
st at i c=" t r ue" / >
<bean cl ass=" com. opensymphony. xwor k2. ut i l . XWor kConver t er "
st at i c=" t r ue" / >
<bean cl ass=" com. opensymphony. xwor k2. ut i l . Ognl Val ueSt ack"
st at i c=" t r ue" / >
<bean cl ass=" or g. apache. st r ut s2. di spat cher . Di spat cher "
st at i c=" t r ue" / >
<bean cl ass=" or g. apache. st r ut s2. component s. I ncl ude"
st at i c=" t r ue" / >
<bean cl ass=" or g. apache. st r ut s2. di spat cher . Fi l t er Di spat cher "
st at i c=" t r ue" / >
<bean cl ass=" or g. apache. st r ut s2. vi ews. ut i l . Cont ext Ut i l "
st at i c=" t r ue" / >
232 STRUTS RA-MA

<bean cl ass=" or g. apache. st r ut s2. vi ews. ut i l . Ur l Hel per "
st at i c=" t r ue" / >

<package name="struts-default" abstract="true">
<r esul t - t ypes>
<r esul t - t ype name=" chai n"
cl ass=" com. opensymphony. xwor k2. Act i onChai nResul t " / >
<r esul t - t ype name=" di spat cher "
cl ass=" or g. apache. st r ut s2. di spat cher . Ser vl et Di spat cher Resul t "
def aul t =" t r ue" / >
<r esul t - t ype name=" f r eemar ker "
cl ass=" or g. apache. st r ut s2. vi ews. f r eemar ker . Fr eemar ker Resul t " / >
<r esul t - t ype name=" ht t pheader "
cl ass=" or g. apache. st r ut s2. di spat cher . Ht t pHeader Resul t " / >
<r esul t - t ype name=" r edi r ect "
cl ass=" or g. apache. st r ut s2. di spat cher . Ser vl et Redi r ect Resul t " / >
<r esul t - t ype name=" r edi r ect Act i on"
cl ass=" or g. apache. st r ut s2. di spat cher . Ser vl et Act i onRedi r ect Resul t " / >
<r esul t - t ype name=" st r eam"
cl ass=" or g. apache. st r ut s2. di spat cher . St r eamResul t " / >
<r esul t - t ype name=" vel oci t y"
cl ass=" or g. apache. st r ut s2. di spat cher . Vel oci t yResul t " / >
<r esul t - t ype name=" xsl t "
cl ass=" or g. apache. st r ut s2. vi ews. xsl t . XSLTResul t " / >
<r esul t - t ype name=" pl ai nText "
cl ass=" or g. apache. st r ut s2. di spat cher . Pl ai nText Resul t " / >
<! - - Depr ecat ed name f or mschedul ed f or r emoval i n
St r ut s 2. 1. 0. The camel Case ver si ons ar e pr ef er r ed. See ww- 1707 - - >
<r esul t - t ype name=" r edi r ect - act i on"
cl ass=" or g. apache. st r ut s2. di spat cher . Ser vl et Act i onRedi r ect Resul t " / >
<r esul t - t ype name=" pl ai nt ext "
cl ass=" or g. apache. st r ut s2. di spat cher . Pl ai nText Resul t " / >
</ r esul t - t ypes>


<i nt er cept or s>
<i nt er cept or name=" al i as"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Al i asI nt er cept or " / >
<i nt er cept or name=" aut owi r i ng"
cl ass=" com. opensymphony. xwor k2. spr i ng. i nt er cept or . Act i onAut owi r i ngI n
t er cept or " / >
<i nt er cept or name=" chai n"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Chai ni ngI nt er cept or " / >
<i nt er cept or name=" conver si onEr r or "
cl ass=" or g. apache. st r ut s2. i nt er cept or . St r ut sConver si onEr r or I nt er cept
or " / >
<i nt er cept or name=" cooki e"
cl ass=" or g. apache. st r ut s2. i nt er cept or . Cooki eI nt er cept or " / >
<i nt er cept or name=" cr eat eSessi on"
cl ass=" or g. apache. st r ut s2. i nt er cept or . Cr eat eSessi onI nt er cept or " / >
<i nt er cept or name=" debuggi ng"
cl ass=" or g. apache. st r ut s2. i nt er cept or . debuggi ng. Debuggi ngI nt er cept or
" / >
<i nt er cept or name=" ext er nal Ref "
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Ext er nal Ref er encesI nt er ce
pt or " / >
<i nt er cept or name=" execAndWai t "
cl ass=" or g. apache. st r ut s2. i nt er cept or . Execut eAndWai t I nt er cept or " / >
RA-MA CAPTULO 8. STRUTS 2 233

<i nt er cept or name=" except i on"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Except i onMappi ngI nt er cept
or " / >
<i nt er cept or name=" f i l eUpl oad"
cl ass=" or g. apache. st r ut s2. i nt er cept or . Fi l eUpl oadI nt er cept or " / >
<i nt er cept or name=" i 18n"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . I 18nI nt er cept or " / >
<i nt er cept or name=" l ogger "
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Loggi ngI nt er cept or " / >
<i nt er cept or name=" model Dr i ven"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Model Dr i venI nt er cept or " / >
<i nt er cept or name=" scopedModel Dr i ven"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . ScopedModel Dr i venI nt er cep
t or " / >
<i nt er cept or name=" par ams"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Par amet er sI nt er cept or " / >
<i nt er cept or name=" pr epar e"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Pr epar eI nt er cept or " / >
<i nt er cept or name=" st at i cPar ams"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . St at i cPar amet er sI nt er cept
or " / >
<i nt er cept or name=" scope"
cl ass=" or g. apache. st r ut s2. i nt er cept or . ScopeI nt er cept or " / >
<i nt er cept or name=" ser vl et Conf i g"
cl ass=" or g. apache. st r ut s2. i nt er cept or . Ser vl et Conf i gI nt er cept or " / >
<i nt er cept or name=" sessi onAut owi r i ng"
cl ass=" or g. apache. st r ut s2. spr i ng. i nt er cept or . Sessi onCont ext Aut owi r i n
gI nt er cept or " / >
<i nt er cept or name=" t i mer "
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Ti mer I nt er cept or " / >
<i nt er cept or name=" t oken"
cl ass=" or g. apache. st r ut s2. i nt er cept or . TokenI nt er cept or " / >
<i nt er cept or name=" t okenSessi on"
cl ass=" or g. apache. st r ut s2. i nt er cept or . TokenSessi onSt or eI nt er cept or " /
>
<i nt er cept or name=" val i dat i on"
cl ass=" or g. apache. st r ut s2. i nt er cept or . val i dat i on. Annot at i onVal i dat i o
nI nt er cept or " / >
<i nt er cept or name=" wor kf l ow"
cl ass=" com. opensymphony. xwor k2. i nt er cept or . Def aul t Wor kf l owI nt er cept o
r " / >
<i nt er cept or name=" st or e"
cl ass=" or g. apache. st r ut s2. i nt er cept or . MessageSt or eI nt er cept or " / >
<i nt er cept or name=" checkbox"
cl ass=" or g. apache. st r ut s2. i nt er cept or . CheckboxI nt er cept or " / >
<i nt er cept or name=" pr of i l i ng"
cl ass=" or g. apache. st r ut s2. i nt er cept or . Pr of i l i ngAct i vat i onI nt er cept or
" / >
<i nt er cept or name=" r ol es"
cl ass=" or g. apache. st r ut s2. i nt er cept or . Rol esI nt er cept or " / >

<! - - Basi c st ack - - >
<i nt er cept or - st ack name=" basi cSt ack" >
<i nt er cept or - r ef name=" except i on" / >
<i nt er cept or - r ef name=" ser vl et Conf i g" / >
<i nt er cept or - r ef name=" pr epar e" / >
<i nt er cept or - r ef name=" checkbox" / >
<i nt er cept or - r ef name=" par ams" / >
<i nt er cept or - r ef name=" conver si onEr r or " / >
234 STRUTS RA-MA

</ i nt er cept or - st ack>

<! - - Sampl e val i dat i on and wor kf l ow st ack - - >
<i nt er cept or - st ack name=" val i dat i onWor kf l owSt ack" >
<i nt er cept or - r ef name=" basi cSt ack" / >
<i nt er cept or - r ef name=" val i dat i on" / >
<i nt er cept or - r ef name=" wor kf l ow" / >
</ i nt er cept or - st ack>

<! - - Sampl e f i l e upl oad st ack - - >
<i nt er cept or - st ack name=" f i l eUpl oadSt ack" >
<i nt er cept or - r ef name=" f i l eUpl oad" / >
<i nt er cept or - r ef name=" basi cSt ack" / >
</ i nt er cept or - st ack>

<! - - Sampl e model - dr i ven st ack - - >
<i nt er cept or - st ack name=" model Dr i venSt ack" >
<i nt er cept or - r ef name=" model Dr i ven" / >
<i nt er cept or - r ef name=" basi cSt ack" / >
</ i nt er cept or - st ack>

<! - - Sampl e act i on chai ni ng st ack - - >
<i nt er cept or - st ack name=" chai nSt ack" >
<i nt er cept or - r ef name=" chai n" / >
<i nt er cept or - r ef name=" basi cSt ack" / >
</ i nt er cept or - st ack>

<! - - Sampl e i 18n st ack - - >
<i nt er cept or - st ack name=" i 18nSt ack" >
<i nt er cept or - r ef name=" i 18n" / >
<i nt er cept or - r ef name=" basi cSt ack" / >
</ i nt er cept or - st ack>

<! - - An exampl e of t he par ams- pr epar e- par ams t r i ck. Thi s
st ack
i s exact l y t he same as t he def aul t St ack, except
t hat i t
i ncl udes one ext r a i nt er cept or bef or e t he pr epar e
i nt er cept or :
t he par ams i nt er cept or .

Thi s i s usef ul f or when you wi sh t o appl y
par amet er s di r ect l y
t o an obj ect t hat you wi sh t o l oad ext er nal l y ( such
as a DAO
or dat abase or ser vi ce l ayer ) , but can' t l oad t hat
obj ect
unt i l at l east t he I D par amet er has been l oaded. By
l oadi ng
t he par amet er s t wi ce, you can r et r i eve t he obj ect
i n t he
pr epar e( ) met hod, al l owi ng t he second par ams
i nt er cept or t o
appl y t he val ues on t he obj ect . - - >
<i nt er cept or - st ack name=" par amsPr epar ePar amsSt ack" >
<i nt er cept or - r ef name=" except i on" / >
<i nt er cept or - r ef name=" al i as" / >
<i nt er cept or - r ef name=" par ams" / >
<i nt er cept or - r ef name=" ser vl et Conf i g" / >
RA-MA CAPTULO 8. STRUTS 2 235

<i nt er cept or - r ef name=" pr epar e" / >
<i nt er cept or - r ef name=" i 18n" / >
<i nt er cept or - r ef name=" chai n" / >
<i nt er cept or - r ef name=" model Dr i ven" / >
<i nt er cept or - r ef name=" f i l eUpl oad" / >
<i nt er cept or - r ef name=" checkbox" / >
<i nt er cept or - r ef name=" st at i cPar ams" / >
<i nt er cept or - r ef name=" par ams" / >
<i nt er cept or - r ef name=" conver si onEr r or " / >
<i nt er cept or - r ef name=" val i dat i on" >
<par am
name=" excl udeMet hods" >i nput , back, cancel </ par am>
</ i nt er cept or - r ef >
<i nt er cept or - r ef name=" wor kf l ow" >
<par am
name=" excl udeMet hods" >i nput , back, cancel </ par am>
</ i nt er cept or - r ef >
</ i nt er cept or - st ack>

<! - - A compl et e st ack wi t h al l t he common i nt er cept or s
i n pl ace.
Gener al l y, t hi s st ack shoul d be t he one you use,
t hough i t
may do mor e t han you need. Al so, t he or der i ng can
be
swi t ched ar ound ( ex: i f you wi sh t o have your
ser vl et - r el at ed
obj ect s appl i ed bef or e pr epar e( ) i s cal l ed, you' d
need t o move
ser vl et - conf i g i nt er cept or up.

Thi s st ack al so excl udes f r omt he nor mal val i dat i on
and wor kf l ow
t he met hod names i nput , back, and cancel . These
t ypi cal l y ar e
associ at ed wi t h r equest s t hat shoul d not be
val i dat ed.
- - >
<i nt er cept or - st ack name=" def aul t St ack" >
<i nt er cept or - r ef name=" except i on" / >
<i nt er cept or - r ef name=" al i as" / >
<i nt er cept or - r ef name=" ser vl et Conf i g" / >
<i nt er cept or - r ef name=" pr epar e" / >
<i nt er cept or - r ef name=" i 18n" / >
<i nt er cept or - r ef name=" chai n" / >
<i nt er cept or - r ef name=" debuggi ng" / >
<i nt er cept or - r ef name=" pr of i l i ng" / >
<i nt er cept or - r ef name=" scopedModel Dr i ven" / >
<i nt er cept or - r ef name=" model Dr i ven" / >
<i nt er cept or - r ef name=" f i l eUpl oad" / >
<i nt er cept or - r ef name=" checkbox" / >
<i nt er cept or - r ef name=" st at i cPar ams" / >
<i nt er cept or - r ef name=" par ams" >
<par amname=" excl udePar ams" >doj o\ . . *</ par am>
</ i nt er cept or - r ef >
<i nt er cept or - r ef name=" conver si onEr r or " / >
<i nt er cept or - r ef name=" val i dat i on" >
<par am
name=" excl udeMet hods" >i nput , back, cancel , br owse</ par am>
236 STRUTS RA-MA

</ i nt er cept or - r ef >
<i nt er cept or - r ef name=" wor kf l ow" >
<par am
name=" excl udeMet hods" >i nput , back, cancel , br owse</ par am>
</ i nt er cept or - r ef >
</ i nt er cept or - st ack>

<! - - The compl et eSt ack i s her e f or backwar ds
compat i bi l i t y f or
appl i cat i ons t hat st i l l r ef er t o t he def aul t St ack
by t he
ol d name - - >
<i nt er cept or - st ack name=" compl et eSt ack" >
<i nt er cept or - r ef name=" def aul t St ack" / >
</ i nt er cept or - st ack>

<! - - Sampl e execut e and wai t st ack.
Not e: execAndWai t shoul d al ways be
t he *l ast * i nt er cept or . - - >
<i nt er cept or - st ack name=" execut eAndWai t St ack" >
<i nt er cept or - r ef name=" execAndWai t " >
<par amname=" excl udeMet hods" >
i nput , back, cancel </ par am>
</ i nt er cept or - r ef >
<i nt er cept or - r ef name=" def aul t St ack" / >
<i nt er cept or - r ef name=" execAndWai t " >
<par amname=" excl udeMet hods" >
i nput , back, cancel </ par am>
</ i nt er cept or - r ef >
</ i nt er cept or - st ack>

<! - - Depr ecat ed name f or ms schedul ed f or r emoval i n
St r ut s 2. 1. 0. The camel Case
ver si ons ar e pr ef er r ed. See ww- 1707 - - >
<i nt er cept or name=" ext er nal - r ef "
cl ass=" com. opensymphony. xwor k2.
i nt er cept or . Ext er nal Ref er encesI nt er cept or " / >
<i nt er cept or name=" model - dr i ven"
cl ass=" com. opensymphony. xwor k2.
i nt er cept or . Model Dr i venI nt er cept or " / >
<i nt er cept or name=" st at i c- par ams"
cl ass=" com. opensymphony. xwor k2.
i nt er cept or . St at i cPar amet er sI nt er cept or " / >
<i nt er cept or name=" scoped- model - dr i ven"
cl ass=" com. opensymphony. xwor k2.
i nt er cept or . ScopedModel Dr i venI nt er cept or " / >
<i nt er cept or name=" ser vl et - conf i g"
cl ass=" or g. apache. st r ut s2.
i nt er cept or . Ser vl et Conf i gI nt er cept or " / >
<i nt er cept or name=" t oken- sessi on"
cl ass=" or g. apache. st r ut s2. i nt er cept or . TokenSessi onSt or eI nt er cept or " /
>

</ i nt er cept or s>

<def aul t - i nt er cept or - r ef name=" def aul t St ack" / >
</ package>

</ st r ut s>
RA-MA CAPTULO 8. STRUTS 2 237

8.1.5.3 MODULARIDAD DE FICHEROS DE CONFIGURACIN
En una aplicacin grande con un elevado nmero de elementos de
configuracin, puede ser conveniente distribuir estas configuraciones en archivos
diferentes. Desde el interior de struts.xml se incluir una referencia a cada uno de
estos archivos mediante el elemento <include>, el cual indicar en su atributo file
la ruta relativa del archivo a incluir.
El siguiente ejemplo distribuye la configuracin de la aplicacin en tres
archivos .xml, incluyendo cada uno de ellos la configuracin de cada rol que opera
en la aplicacin:
<st r ut s>
<i ncl ude f i l e=" admi ni st r ador . xml " / >
<i ncl ude f i l e=" t ut or . xml " / >
<i ncl ude f i l e=" al umno. xml " / >
</ st r ut s>
Cada archivo incluido tendr exactamente la misma estructura que
cualquier archivo de configuracin struts.xml.
8.2 BENEFICIOS DEL USO DE STRUTS 2
Del anlisis que hemos ido realizando sobre los componentes de este nuevo
framework se deducen ya algunos de los beneficios que su uso aporta a los
programadores de aplicaciones Web. A continuacin resumimos las principales
caractersticas clave que aporta este nuevo framework:
Acciones de tipo POJO. La posibilidad de utilizar clases simples
para implementar las acciones reduce la complejidad del desarrollo
de las mismas y permite un desacoplamiento entre capas.
Eliminacin de ActionForms. Las clases de accin permiten
disponer de propiedades para almacenar los datos de usuario,
haciendo innecesario el empleo de un nuevo tipo de clase
adicional.
Flexibilidad en el diseo de las vistas. La posibilidad de utilizar
distintas tecnologas para la generacin de una vista en
aplicaciones Struts 2, tales como J SP, velocity o freemaker,
proporciona una gran flexibilidad en el diseo de las mismas y
ofrece un gran variedad de posibilidades a los desarrolladores.
238 STRUTS RA-MA

Amplia librera de acciones. El nmero de acciones
personalizadas para la generacin de la vista y las capacidades de
stas han aumentado respecto a versiones anteriores del
framework.
Posibilidad de utilizar anotaciones. Como alternativa al uso de
ficheros XML, Struts 2 soporta el uso de anotaciones para definir
diferentes parmetros de configuracin en las acciones, reduciendo
la complejidad de la aplicacin.
Configuraciones por defecto. La posibilidad de disponer de una
serie de opciones de configuracin predefinidas simplifica
enormemente la labor del desarrollador.
Soporte para AJAX. La utilizacin de AJ AX en el desarrollo de
aplicaciones para Web ha supuesto una enorme reduccin en el
tiempo de respuesta de las mismas, mejorando adems la
experiencia de los usuarios con la interfaz grfica. Struts 2
proporciona una serie de tags que permiten aadir capacidades
AJ AX a las aplicaciones.
8.3 CREACIN DE UNA APLICACIN DE EJEMPLO DE
STRUTS 2
Seguidamente se va a explicar cmo crear una sencilla aplicacin Web de
ejemplo con Struts 2, la cual nos servir para conocer el funcionamiento del
framework y aprender a crear y configurar los elementos principales.
La construccin de la aplicacin puede realizarse de forma manual o
utilizando algn IDE, como por ejemplo Eclipse o NetBeans.
8.3.1 Descarga del paquete de distribucin de Struts 2
Lo primero que tenemos que hacer ser descargar la ltima versin del
paquete de distribucin de Struts 2 desde la pgina http://struts.apache.org/2.x/.
Este paquete de distribucin consiste en un archivo .zip en el que se incluyen las
libreras con los distintos componentes del framework, documentacin del API y
una serie de aplicaciones de ejemplo (figura 37).

RA-MA CAPTULO 8. STRUTS 2 239









Fig. 37. Contenido del paquete de distribucin de Struts 2
Si utilizamos un entorno de desarrollo como NetBeans o Eclipse, podemos crear
una librera a la que asociaremos los .jar descargados, a fin de poder aadirla
fcilmente a un proyecto Web en el que queramos hacer uso de este framework.
8.3.2 Requerimientos software
Las aplicaciones Struts 2 pueden ejecutarse con servidores Tomcat 5.0 en
adelante, siendo adems necesario disponer de las siguientes versiones
J ava/J avaEE:
Servlet API 2.3.
J SP API 2.0.
J ava 5.
8.3.3 Descripcin de la aplicacin
La aplicacin de ejemplo que vamos a crear va a consistir en una pgina de
inicio en la que aparecer un enlace que al ser pulsado muestra una pgina con un
mensaje de saludo y la hora del sistema (figura 38).

240 STRUTS RA-MA







Fig. 38. Pginas de la aplicacin de ejemplo
8.3.4 Estructura de directorios de la aplicacin
Al tratarse de una aplicacin Web, la estructura de directorios de la misma
ser la correspondiente a cualquier aplicacin J avaEE. En este sentido, hemos de
tener en cuenta que debemos incluir en el directorio WEB-INF\lib de la aplicacin
las libreras Struts 2 necesarias para el funcionamiento de la aplicacin, que como
mnimo deben ser: commons-logging-1.0.4.jar, freemarker-2.3.8.jar, ognl-
2.6.11.jar, struts2-core-2.0.11.jar y xwork-2.0.4.jar.
Suponiendo que el directorio raz de la aplicacin lo llamamos
ejemplosaludo y teniendo en cuenta que la nica clase de accin que vamos a
utilizar se llamar Saludo, la estructura de directorios de la aplicacin quedar pues
como se indica en la figura 39.







Fig. 39. Estructura de directorios de una aplicacin bsica Struts
RA-MA CAPTULO 8. STRUTS 2 241

En el caso de utilizar un IDE, no debemos preocuparnos de generar la
estructura de directorios anterior, pues el entorno se encargar de hacerlo por
nosotros. Como se indic anteriormente, slo tendremos que aadir la librera de
archivos .jar de Struts 2 al proyecto para poder utilizar el framework.
Cuando se vaya a desarrollar una aplicacin en la que se vaya a hacer uso
de algunos elementos especiales como validadores o tiles, habr que copiar
tambin en el directorio WEB-INF\lib los archivos .jar correspondientes que se
incluyen en el paquete de distribucin para la utilizacin de estos componentes.
8.3.5 Registro de FilterDispatcher
Una vez definida la estructura de directorios, el primer paso ser registrar
el filtro receptor de peticiones FilterDispatcher en el archivo de configuracin
web.xml. Al mismo tiempo, definiremos tambin en este archivo como pgina de
inicio de la aplicacin a inicio.html:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<web- app i d=" WebApp_9" ver si on=" 2. 4"
xml ns=ht t p: / / j ava. sun. com/ xml / ns/ j 2ee
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSchema- i nst ance"
xsi : schemaLocat i on=" ht t p: / / j ava. sun. com/ xml / ns/ j 2ee
ht t p: / / j ava. sun. com/ xml / ns/ j 2ee/ web- app_2_4. xsd" >

<di spl ay- name>St r ut s ej empl o</ di spl ay- name>
<f i l t er >
<f i l t er - name>st r ut s2</ f i l t er - name>
<f i l t er - cl ass>or g. apache. st r ut s2.
di spat cher . Fi l t er Di spat cher
</ f i l t er - cl ass>
</ f i l t er >
<f i l t er - mappi ng>
<f i l t er - name>st r ut s2</ f i l t er - name>
<ur l - pat t er n>/ *</ ur l - pat t er n>
</ f i l t er - mappi ng>
<wel come- f i l e- l i st >
<wel come- f i l e>i ni ci o. ht ml </ wel come- f i l e>
</ wel come- f i l e- l i st >
</ web- app>
242 STRUTS RA-MA

8.3.6 Implementacin de la clase de accin
En este ejemplo crearemos una nica clase de accin, a la que como hemos
visto llamaremos Saludo, que ser invocada desde la pgina inicio.html cuando se
pulse sobre el enlace. El cdigo de esta clase se muestra en el siguiente listado:
package mi ej empl o;
i mpor t j ava. ut i l . Dat e;
publ i c cl ass Sal udo {
publ i c st at i c f i nal St r i ng t ext o=
" Bi enveni do a St r ut s 2" ;
pr i vat e St r i ng mensage;
publ i c St r i ng execut e( ) t hr ows Except i on {
set Mensage( t ext o) ;
r et ur n " ok" ;
}
publ i c voi d set Mensage( St r i ng mensage) {
t hi s. mensage = mensage;
}
publ i c St r i ng get Mensage( ) {
r et ur n mensage;
}
publ i c St r i ng get FechaHor a( ) {
r et ur n new Dat e( ) . t oSt r i ng( ) ;
}
}
Como vemos se trata de una clase normal J ava en la que hemos definido un
mtodo, que por convenio se llamar siempre execute en todas las clases de
accin, donde se incluyen las instrucciones asociadas a la accin y que en este
ejemplo simplemente consistirn en almacenar un texto dentro de la propiedad
mensaje del objeto. Este mtodo deber devolver una cadena de caracteres que
ser utilizada para determinar el resultado que deber ser enviado al cliente.
Adems de execute(), nuestra clase de accin de ejemplo cuenta con dos
propiedades: mensaje, que contiene un texto con el mensaje a mostrar al usuario,
y fechaHora, que contiene la fecha y hora actual del sistema. Esta ltima
propiedad no necesita de ningn dato miembro para el almacenamiento de su valor
ni, por tanto, de un mtodo de tipo set, puesto que el valor de la misma se
determinar en cada momento instanciando un objeto Date.
RA-MA CAPTULO 8. STRUTS 2 243

8.3.7 Registro de la clase de accin
Las clases de accin deben ser registradas en struts.xml mediante el
elemento <action>dentro de un determinado paquete. Cada accin ser registrada
en su elemento <action>correspondiente, el cual deber definir los siguientes
atributos:
name. Nombre asociado a la accin. Ser el nombre utilizado en la
URL de acceso a la accin.
class. Clase que implementa la accin.
8.3.8 Reglas de navegacin
Como hemos visto en la implementacin de la accin anterior, el mtodo
execute() devuelve una cadena de caracteres que ser utilizada por el controlador
para determinar la vista que debe ser procesada tras la ejecucin de la accin.
Cada uno de los posibles resultados que se vayan a generar al usuario para
la accin deber ser definido dentro de sta mediante un elemento <result>, en lo
que se conoce como reglas de navegacin de la aplicacin. Cada uno de estos
elementos definir en su atributo name el nombre asociado a este resultado,
nombre que es utilizado por las clases de accin para referirse al mismo, mientras
que en el cuerpo del elemento se indicar la URL asociada al resultado.
En nuestro ejemplo, el registro de la accin con su <result>asociado
quedar como se indica en el siguiente listado, donde el resultado es implementado
mediante una pgina J SP:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE st r ut s PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s Conf i gur at i on
2. 0/ / EN"
" ht t p: / / st r ut s. apache. or g/ dt ds/ st r ut s- 2. 0. dt d" >
<st r ut s>
<package name=" ej empl o" namespace=" / ej empl o"
ext ends=" st r ut s- def aul t " >
<act i on name=" sal udo" cl ass=" mi ej empl o. Sal udo" >
<r esul t name=" ok" >/ sal udo. j sp</ r esul t >
</ act i on>
</ package>
</ st r ut s>
244 STRUTS RA-MA

8.3.8.1 ACCIN POR DEFECTO
Cuando se quiere navegar directamente desde una pgina a otra sin
necesidad de procesar ningn tipo de accin, se deber utilizar la conocida como
accin por defecto.
La accin por defecto en Struts 2 tiene como nombre Name y su nica
funcin es dirigir la peticin a una determinada vista. As pues, si en una pgina
queremos incluir, por ejemplo, un enlace que al ser pulsado nos lleve a otra pgina,
se deber utilizar la siguiente instruccin:
<a hr ef = " Name. act i on" > I r a ot r a pgi na </ a>
En la regla de navegacin correspondiente a la accin Name se especificar
la URL de la pgina destino:
<act i on name=" Name" >
<r esul t >/ pagi nadest i no. j sp</ r esul t >
</ act i on>
Como podemos ver, el elemento result en este caso no tiene que indicar
ningn valor para el atributo name, pues la accin por defecto nicamente puede
definir un result.
8.3.9 Vistas
Como en cualquier aplicacin Web, las vistas son generadas mediante
pginas estticas XHTML o, en el caso de respuestas dinmicas, a travs de J SP.
La pgina de inicio de la aplicacin es una simple pgina XHTML con un
enlace que apunta a la accin saludo:
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 0
Tr ansi t i onal / / EN" >
<ht ml >
<head>
<t i t l e>Ej empl o de St r ut s</ t i t l e>
</ head>
<body>
<br / ><br / >
<p al i gn=" cent er " >Par a ent r ar en St r ut s 2 pul se
<a hr ef =" ej empl o/ sal udo. act i on" > Aqu </ a>
</ p>
</ body>
RA-MA CAPTULO 8. STRUTS 2 245

</ ht ml >
Como vemos, la URL incluida en el atributo href del enlace es una URL
relativa a la aplicacin Web y est formada por el valor incluido en el atributo
namespace del elemento <package>, seguido del nombre de la accin terminada
con la extensin .action.
Por su parte, la pgina de resultado que se procesa tras ejecutar la accin es
una pgina J SP que muestra el mensaje de saludo definido en la accin, as como la
hora del sistema. El cdigo de esta pgina se muestra en el siguiente listado:
<%@page cont ent Type=" t ext / ht ml ; char set =UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<ht ml >
<head>
<t i t l e>Resul t ado de ej empl o</ t i t l e>
</ head>

<body>
<h1><s: pr oper t y val ue=" message" / ></ h1>
<h3>Fecha act ual : <b><s: pr oper t y val ue=" f echaHor a" / ></ b></ h3>
</ body>
</ ht ml >
Los datos mostrados por la pgina son obtenidos a partir de las propiedades
message y fechaHora del objeto de accin.
Mediante el tag <s:property>de Struts 2 es posible acceder desde la
pgina de resultados a cualquiera de las propiedades del objeto Action que se
acaba de ejecutar. Este tag dispone de un atributo llamado value que contiene el
nombre de la propiedad cuyo valor se quiere recuperar.
8.4 UTILIZACIN DE INTERCEPTORES
Como ya dijimos anteriormente, los interceptores son un nuevo tipo de
componentes incluidos en la arquitectura Struts 2 que se ejecutan antes y despus
del procesamiento de una peticin por parte de un objeto de accin.
El API de Struts 2 incluye un gran nmero de interceptores predefinidos
que podemos utilizar en cualquiera de nuestras aplicaciones Web, siendo tambin
posible la creacin de interceptores personalizados.
246 STRUTS RA-MA

Los interceptores son asignados a nivel de accin, es decir, el programador
decide a travs de struts.xml qu interceptor o interceptores van a ser ejecutados
con cada accin.
La utilizacin de interceptores en una aplicacin requiere realizar dos
sencillas tareas en el archivo de configuracin struts.xml:
Declaracin del interceptor.
Asignacin del interceptor a la accin.
8.4.1 Declaracin del interceptor
Un interceptor se declara en el interior del elemento <interceptors>
utilizando un elemento <interceptor>, el cual dispone de los siguientes atributos:
name. Nombre asignado al interceptor.
class. Clase a la que pertenece el interceptor.
El elemento <interceptors>debe estar situado directamente en el interior
del elemento <package>. Por ejemplo, el siguiente bloque declara el interceptor
FileUploadInterceptor de Struts 2, utilizado para facilitar el acceso a los ficheros
subidos al servidor desde el cliente:
<st r ut s>
<package. . . >
:
<i nt er cept or s>
<interceptor name="fileUpload"
class="org.apache.struts2.
interceptor.FileUploadInterceptor"/>
:
</ i nt er cept or s>
Tambin es posible declarar un grupo o pila de interceptores para permitir
que puedan ser aplicados en bloque sobre una accin. En este caso, deber
previamente haberse declarado cada uno de los interceptores que componen el
bloque mediante el elemento <interceptor> anterior, definindose despus el
bloque a travs del elemento <interceptor-stack>.
RA-MA CAPTULO 8. STRUTS 2 247

Un elemento <interceptor-stack>dispone del atributo name que permite
asignar un nombre al bloque. En su interior se utilizar un elemento <interceptor-
ref>para referenciar de manera individualizada a cada uno de los interceptores que
componen el bloque.
Al igual que <interceptor>, los elementos <interceptor-stack>se deben
incluir en el interior de <interceptors>, siempre despus de la declaracin de los
interceptores individuales.
El siguiente ejemplo declara dos interceptores y una pila de interceptores
constituida por stos:
<st r ut s>
<package. . . >
:
<i nt er cept or s>
<i nt er cept or name=" f i l eUpl oad"
cl ass=" or g. apache. st r ut s2.
i nt er cept or . Fi l eUpl oadI nt er cept or " / >
<i nt er cept or name=" par ams"
cl ass=" com. opensymphony. xwor k2.
i nt er cept or . Par amet er sI nt er cept or " / >
<interceptor-stack name="ejemplostack">
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="params"/>
</interceptor-stack>
:
</ i nt er cept or s>
Mediante el atributo name de <interceptor-ref>se indicar el nombre del
interceptor que se quiere incluir en la pila.
Tambin pueden incluirse dentro de una pila otras pilas existentes, en este
caso el atributo name del elemento <interceptor-ref>deber hacer referencia al
nombre del grupo a incluir.
Como podemos ver en el listado que se present en el apartado dedicado a
la introduccin de los interceptores, el archivo de configuracin struts-defaul.xml
incluye la declaracin de todos los interceptores del API de Struts 2, as como la de
una serie de grupos cuyos interceptores suelen utilizarse habitualmente en las
acciones.
248 STRUTS RA-MA

8.4.2 Asignacin de un interceptor a una accin
Un interceptor o grupo de interceptores se asigna a una accin a travs de
un elemento <interceptor-ref>utilizado en el interior de <action>. Por ejemplo, si
quisiramos asignar el grupo creado en el ejemplo anterior a la accin personal,
deberamos incluir lo siguiente:
<act i on name=" per sonal " cl ass=" pack. Per sonal " >
<! - - aqu se i ncl ui r an l os r esul t ados- - >
:
<interceptor-ref name="ejemplostack"/>
</ act i on>
Tambin es posible asignar un interceptor o pila de interceptores por
defecto, de manera que se aplique automticamente a cualquier accin definida en
struts.xml. Para esto utilizaremos el elemento <default-interceptor-ref>, tal y
como se indica en el siguiente ejemplo:
<def aul t - i nt er cept or - r ef name=" ej empl ost ack" / >
La anterior etiqueta se incluir directamente en el interior del elemento
<package>.
Si observamos el contenido del archivo struts-default.xml presentado
anteriormente, veremos que existe una asignacin por defecto del grupo de
interceptores defaultStack:
<def aul t - i nt er cept or - r ef name=" def aul t St ack" / >
Dado que todas las aplicaciones suelen heredar este archivo de
configuracin, lo anterior significa pues que cualquier accin creada en una
aplicacin se beneficiar de la funcionalidad proporcionada por todos los
interceptores definidos en este grupo sin que el programador tenga que escribir
una sola lnea de cdigo y, ni siquiera, ningn elemento de configuracin adicional.
8.4.3 Inyeccin de dependencia
La inyeccin de dependencia es una tcnica empleada por los interceptores
que permite a los objetos de accin tener acceso a ciertos datos necesarios para
poder procesar la peticin.
Como hemos tenido oportunidad de comprobar, al tratarse de objetos
POJ O las clases de accin no heredan ninguna clase base del framework, ni su
RA-MA CAPTULO 8. STRUTS 2 249

mtodo execute() recibe ningn tipo de parmetro durante su ejecucin, por lo que
de forma predeterminada no tienen acceso a ninguno de los objetos del contexto de
aplicacin, como son el objeto request, response, session, etc.
A travs de la inyeccin de dependencia es posible proporcionar acceso a
estos objetos desde el interior de una clase de accin en caso de que ello resulte
necesario. Esta funcionalidad es proporcionada por el interceptor
ServletConfigInterceptor, el cual forma parte del grupo de interceptores por defecto
dafaultStack que, como indicamos anteriormente, se encuentra asociado de
forma predeterminada a todas las acciones de la aplicacin que se encuentren
registradas en el interior del elemento <package>que herede struts-default.
El interceptor ServletConfigInterceptor trabaja conjuntamente con una
serie de interfaces que la clase de accin tendr que implementar para poder tener
acceso a los distintos tipos de objetos. Estas interfaces son:
ServletContextAware. Proporciona acceso al objeto
ServletContext.
ServletRequestAware. Proporciona acceso al objeto
HttpServletRequest.
ServletResponseAware. Proporciona acceso al objeto
HttpServletResponse.
PrincipalAware. Proporciona acceso a un objeto PrincipalProxy
que permite obtener informacin relacionada con la seguridad.
ParameterAware. Proporciona acceso a todos los parmetros
enviados en la peticin.
RequestAware. Proporciona acceso a todas las variables de
peticin.
SessionAware. Proporciona acceso a todas las variables de sesin.
ApplicationAware. Proporciona acceso a todas las variables de
aplicacin.
Todas ellas, salvo ServletContextAware que se encuentra en el paquete
org.apache.struts2.util, estn definidas en org.apache.struts2.interceptor.
250 STRUTS RA-MA

Estas interfaces proporcionan un nico mtodo llamado setXxx, donde Xxx
representa el nombre del objeto al que dan acceso. Por ejemplo, la interfaz
ServletContextAware dispone del mtodo setServletContext(), mientras que
ServletRequestAware declara el mtodo setServletRequest().
Los mtodos de estas interfaces reciben como parmetro un objeto que es
inyectado por el interceptor ServletConfigInterceptor durante el procesamiento de
la peticin. En el caso de las cuatro primeras interfaces indicadas el parmetro
corresponde al objeto de contexto de aplicacin al que dan acceso (ServletContext,
ServletRequest, ServletResponse, PrincipalProxy), mientras que en las cuatro
restantes se tratar de una coleccin de tipo Map con los datos o parmetros
existentes en el mbito indicado.
Por ejemplo, utilizando la interfaz SessionAware la siguiente clase de
accin comprobar la existencia de una variable de sesin llamada user,
generando un resultado diferente en cada caso:
i mpor t j ava. ut i l . *;
i mpor t or g. apache. st r ut s2. i nt er cept or
publ i c cl ass Compr obar Act i on i mpl ement s Sessi onAwar e{
pr i vat e Map var i abl es;
publ i c voi d set Sessi on( Map var i abl es) {
t hi s. var i abl es=var i abl es;
}
publ i c St r i ng execut e( ) {
i f ( var i abl es. get ( " user " ) ! =nul l ) {
r et ur n " ok" ;
}
el se{
r et ur n " er r or " ;
}
}
}
En esta otra clase de accin se utiliza la interfaz ServletContextAware para
acceder a una variable de aplicacin que lleva la cuenta del nmero de veces que se
ha ejecutado la accin:
i mpor t j avax. ser vl et . *;
i mpor t or g. apache. st r ut s2. i nt er cept or
publ i c cl ass Compr obar Act i on i mpl ement s Ser vl et Cont ext Awar e{
pr i vat e Ser vl et Cont ext cont ext ;
RA-MA CAPTULO 8. STRUTS 2 251

publ i c voi d set Ser vl et Cont ext ( Ser vl et Cont ext cont ext ) {
t hi s. cont ext =cont ext ;
}
publ i c St r i ng execut e( ) {
I nt eger cont =( I nt eger ) cont ext .
get At t r i but e( " cont ador " ) ;
i f ( cont ! =nul l ) {
cont ++;
}
el se{
cont =1;
}
cont ext . set At t r i but e( " cont ador " , cont ) ;
r et ur n " done" ;
}
}
PRCTICA 8.1. VALIDACIN DE USUARIOS
Descripcin
En esta prctica vamos a desarrollar el mdulo de validacin de usuarios
que hemos estado utilizando en algunas prcticas de Captulos anteriores, donde a
travs de una pgina de login se solicitar al usuario su identificador y password.








Fig. 40. Pginas de la aplicacin
252 STRUTS RA-MA

Si la combinacin es vlida se mostrar una pgina de bienvenida al
usuario, mientras que si no lo es se le redirigir a una pgina de error (figura 40).
Desarrollo
Para validar los datos del usuario utilizaremos una clase de accin que
implementar las interfaces org.apache.struts2.interceptor.ServletRequestAware y
org.apache.struts2.util.ServletContextAware, las cuales nos proporcionarn acceso
a los objetos HttpServletRequest y ServletContext, respectivamente. Mediante
estos objetos podremos acceder a los datos enviados en la peticin as como a los
parmetros de contexto en los que se encuentran almacenados los parmetros de
conexin con la base de datos.
Los credenciales del usuario sern expuestos mediante dos propiedades del
objeto de accin a fin de que sean accesibles fcilmente desde las pginas J SP de la
vista, en las que se utilizar el tag <s:property>para recuperar ambos valores.
Utilizaremos una clase adicional, muy similar a la clase GestionClientes
empleada en prcticas anteriores, para incluir la lgica de validacin de usuarios
contra la base de datos. Esta clase se apoyar a su vez en una clase Datos para
obtener las conexiones con la base de datos.
Listado
A continuacin mostramos el cdigo de los diferentes componentes que
forman la aplicacin.
web.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<web- app i d=" WebApp_9" ver si on=" 2. 4"
xml ns=" ht t p: / / j ava. sun. com/ xml / ns/ j 2ee"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSchema- i nst ance"
xsi : schemaLocat i on=" ht t p: / / j ava. sun. com/ xml / ns/ j 2ee
ht t p: / / j ava. sun. com/ xml / ns/ j 2ee/ web- app_2_4. xsd" >
<cont ext - par am>
<par am- name>dr i ver </ par am- name>
<par am- val ue>sun. j dbc. odbc. J dbcOdbcDr i ver
</ par am- val ue>
</ cont ext - par am>
<cont ext - par am>
<par am- name>cadenaCon</ par am- name>
<par am- val ue>j dbc: odbc: t el ef oni a</ par am- val ue>
RA-MA CAPTULO 8. STRUTS 2 253

</ cont ext - par am>
<f i l t er >
<f i l t er - name>st r ut s2</ f i l t er - name>
<f i l t er - cl ass>or g. apache. st r ut s2.
di spat cher . Fi l t er Di spat cher
</ f i l t er - cl ass>
</ f i l t er >
<f i l t er - mappi ng>
<f i l t er - name>st r ut s2</ f i l t er - name>
<ur l - pat t er n>/ *</ ur l - pat t er n>
</ f i l t er - mappi ng>

<wel come- f i l e- l i st >
<wel come- f i l e>pages/ l ogi n. ht ml </ wel come- f i l e>
</ wel come- f i l e- l i st >
</ web- app>
struts.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE st r ut s PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s Conf i gur at i on
2. 0/ / EN"
" ht t p: / / st r ut s. apache. or g/ dt ds/ st r ut s- 2. 0. dt d" >

<st r ut s>
<package name=" val i daci on" namespace=" / "
ext ends=" st r ut s- def aul t " >
<! - - r egi st r o de l a cl ase de acci n y l as dos pgi nas
de r esul t ado asoci adas a l a mi sma- - >
<act i on name=" Logi n" cl ass=" mi scl ases. Val i dar " >
<r esul t name=" ok" >/ pages/ ok. j sp</ r esul t >
<r esul t name=" er r or " >/ pages/ er r or . j sp</ r esul t >
</ act i on>
</ st r ut s>
Validar.java
package mi scl ases;
i mpor t or g. apache. st r ut s2. i nt er cept or . *;
i mpor t or g. apache. st r ut s2. ut i l . *;
i mpor t j avax. ser vl et . ht t p. *;
254 STRUTS RA-MA

i mpor t j avax. ser vl et . *;

publ i c cl ass Val i dar i mpl ement s Ser vl et Request Awar e,
Ser vl et Cont ext Awar e{
St r i ng pwd;
St r i ng user ;
Ser vl et Cont ext cont ext ;
publ i c St r i ng execut e( ) t hr ows Except i on {
St r i ng dr i ver =cont ext . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=cont ext . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=new
Gest i onCl i ent es( dr i ver , cadenaCon) ;
i f ( gc. val i dar ( user , pwd) )
r et ur n " ok" ;
el se
r et ur n " er r or " ;
}
/ / mt odos de acceso a l as pr opi edades user y pwd
publ i c St r i ng get User ( ) {
r et ur n user ;
}
publ i c St r i ng get Pwd( ) {
r et ur n pwd;
}
/ / mt odos de l as i nt er f aces asoci adas al
/ / i nt er cept or
publ i c voi d set Ser vl et Request (
Ht t pSer vl et Request r equest ) {
pwd=r equest . get Par amet er ( " passwor d" ) ;
user =r equest . get Par amet er ( " user name" ) ;
}
publ i c voi d set Ser vl et Cont ext ( Ser vl et Cont ext cont ext ) {
t hi s. cont ext =cont ext ;
}
}
Datos.java
package mi scl ases;

i mpor t j ava. sql . *;
publ i c cl ass Dat os {
RA-MA CAPTULO 8. STRUTS 2 255

pr i vat e St r i ng dr i ver ;
pr i vat e St r i ng cadenacon;
publ i c Dat os( ) {
}
publ i c Dat os( St r i ng dr i ver , St r i ng cadenacon) {
t hi s. dr i ver =dr i ver ;
t hi s. cadenacon=cadenacon;
}
publ i c Connect i on get Conexi on( ) {
Connect i on cn=nul l ;
t r y{
Cl ass. f or Name( dr i ver ) . newI nst ance( ) ;
cn=Dr i ver Manager . get Connect i on( cadenacon) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
r et ur n cn;
}
publ i c voi d ci er r aConexi on( Connect i on cn) {
t r y{
i f ( cn! =nul l && ! cn. i sCl osed( ) ) {
cn. cl ose( ) ;
}
}
cat ch( SQLExcept i on e) {
e. pr i nt St ackTr ace( ) ;
}
}
}
GestionClientes.java
package mi scl ases;

i mpor t j ava. sql . *;
publ i c cl ass Gest i onCl i ent es {
Dat os dt ;
publ i c Gest i onCl i ent es( St r i ng dr i ver , St r i ng cadenacon) {
dt =new Dat os( dr i ver , cadenacon) ;
}
publ i c bool ean val i dar ( St r i ng user , St r i ng pwd) {
256 STRUTS RA-MA

bool ean est ado=f al se;
t r y{
Connect i on cn=dt . get Conexi on( ) ;
/ / i nst r ucci n SQL par a obt ener l os dat os
/ / del usuar i o i ndi cado
St r i ng quer y = " sel ect * f r omcl i ent es wher e " ;
quer y+=" passwor d=' " +pwd+" ' and usuar i o=' " +user +" ' " ;
St at ement st =cn. cr eat eSt at ement ( ) ;
Resul t Set r s = st . execut eQuer y( quer y) ;
est ado= r s. next ( ) ;
dt . ci er r aConexi on( cn) ;
}
cat ch( Except i on e) {
e. pr i nt St ackTr ace( ) ;
}
f i nal l y{
r et ur n est ado;
}
}
}
login.html
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<t i t l e>Logi n</ t i t l e>
</ head>
<body>
<br / ><br / ><br / ><br / >
<cent er >
<h1>For mul ar i o de Aut ent i caci n</ h1>
<f or mact i on=" Logi n. act i on" met hod=" post " >
<t abl e>
<t r ><t d>Usuar i o</ t d><t d><i nput t ype=" t ext "
name=" user name" / ></ t d></ t r >
<t r ><t d>Passwor d</ t d><t d><i nput t ype=" passwor d"
name=" passwor d" / ></ t d></ t r >
<t r ><t d al i gn=" cent er " col span=" 2" >
<i nput t ype=" submi t " val ue=" Ent r ar " / ></ t d>
RA-MA CAPTULO 8. STRUTS 2 257

</ t r >
</ t abl e>
</ f or m>
<cent er >
</ body>
</ ht ml >
ok.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<t i t l e>Bi enveni da</ t i t l e>
</ head>
<body>
<cent er >
<h1>Bi enveni do <i ><s: pr oper t y val ue=" user " / ></ i >
a mi pgi na</ h1>
</ cent er >
</ body>
</ ht ml >
error.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<t i t l e>Er r or </ t i t l e>
</ head>
<body>
<cent er >
<h1>Usuar i o no vl i do! ! ! ! </ h1>
258 STRUTS RA-MA

l a combi naci n <s: pr oper t y val ue=" user " / >/
<s: pr oper t y val ue=" pwd" / > no es cor r ect a
</ cent er >
</ body>
</ ht ml >
8.4.4 Interceptores personalizados
Adems de utilizar los incluidos en el ncleo de Struts, un programador
puede crear sus propios interceptores personalizados con sus propias reglas
asociadas para luego poderlos utilizar en sus diferentes desarrollos, lo cual
constituye adems una forma elegante de distribuir funcionalidades entre los
distintos componentes de la aplicacin.
Los interceptores deben implementar la interfaz Interceptor, incluida en
el paquete com.opensymphony.xwork2.interceptor y cuya definicin se muestra en
el siguiente listado:
publ i c i nt er f ace I nt er cept or {
publ i c voi d i ni t ( ) ;
publ i c voi d dest r oy( ) ;
publ i c St r i ng i nt er cept ( Act i onI nvocat i on i nvocat i on) ;
}
De estos tres mtodos, intercept() es el ms importante de ellos, siendo en
ste donde se debern incluir las instrucciones que realicen las tareas asignadas al
interceptor. El mtodo intercept() es invocado por el anterior interceptor de la
cadena o por FilterDispatcher en caso de ser el primero.
La clase AbstractInterceptor, incluida en el mismo paquete que Interceptor,
proporciona una implementacin por defecto de los mtodos de esta interfaz, de
modo que si no necesitamos codificar los mtodos init() y destroy(), podemos
heredar esta clase y sobrescribir nicamente el mtodo intercept(), en vez de
implementar la interfaz.
8.4.4.1 EL MTODO INTERCEPT()
Como ya hemos indicado anteriormente, el mtodo intercept() debe
contener las instrucciones que realicen las acciones asociadas al interceptor. Al
igual que el mtodo execute() de las clases de accin, intercept() devuelve un
String que servir para determinar el resultado a procesar para generar la respuesta
del cliente.
RA-MA CAPTULO 8. STRUTS 2 259

Segn se puede apreciar al examinar el formato del mtodo, intercept()
recibe como parmetro un objeto ActionInvocation el cual nos proporcionar
informacin sobre la peticin en curso y la accin asociada a la misma. A travs de
los mtodos de este objeto el programador podr acceder a los datos de la peticin,
manipular la respuesta cliente e incluso establecer el estado de la accin antes de
que sta sea procesada. Entre los mtodos ms importantes de ActionInvocation
tenemos:
getAction(). Devuelve una referencia al objeto de accin asociado
a la peticin en curso. Utilizando este objeto el programador podr
asignar valores a sus propiedades u obtener los valores de stas a
travs de los mtodos set/get.
getInvocationContext(). Este mtodo devuelve una referencia al
objeto ActionContext que proporciona acceso al contexto de
aplicacin. Utilizando por ejemplo el mtodo get() de este objeto
podemos recuperar una referencia a los distintos objetos del
contexto de la aplicacin, como request, response o session. Entre
los principales mtodos de ActionContext tenemos:
get(Object clave). Como hemos indicado, este mtodo
permite obtener una referencia a cualquiera de los objetos
del contexto de aplicacin, recibiendo como parmetro la
clave asociada al objeto cuya referencia se quiere
recuperar.
La interfaz org.apache.struts2.StrutsStatics define una serie
de constantes que pueden ser utilizadas como argumento
en la llamada al mtodo get() de ActionContext, como por
ejemplo la constante HTTP_REQUEST que permitira
recuperar el objeto HttpServletRequest o la constante
HTTP_RESPONSE que servira para obtener una
referencia a HttpServletResponse:
publ i c St r i ng i nt er cept (
Act i onI nvocat i on i nvocat i on) {
Act i onCont ext cont ext =
i nvocat i on. get I nvocat i onCont ext ( ) ;
//referencia al objeto HttpServletRequest
HttpServletRequest request=
( Ht t pSer vl et Request ) cont ext . get ( HTTP_REQUEST) ;
:
260 STRUTS RA-MA

}
- getParameters(). Devuelve una coleccin de tipo Map
con todos los parmetros enviados en la peticin. Por
ejemplo, si en el interior del mtodo intercept()
quisiramos recuperar el valor del parmetro user
deberamos escribir:
publ i c St r i ng i nt er cept (
Act i onI nvocat i on i nvocat i on) {
Act i onCont ext cont ext =
i nvocat i on. get I nvocat i onCont ext ( ) ;
Map par amet r os=
cont ext . get Par amet er s( ) ;
String us=(String)parametros.get("user");
:
}
- getSession(). Devuelve una coleccin Map con todas las
variables de sesin.
- getApplication(). Devuelve una coleccin Map con todas
las variables de aplicacin.
invoke(). Despus de realizar todas las operaciones el interceptor
deber pasar el control de la aplicacin al siguiente interceptor o,
en caso de tratarse del ltimo elemento de la cadena, invocar al
objeto de accin correspondiente. Esta operacin se lleva a cabo
llamando al mtodo invoke() de ActionInvocation, cuyo valor de
devolucin representar la cadena asociada en struts.xml al
resultado que se debe procesar como respuesta. Es por ello que este
valor deber ser utilizado como valor de retorno del mtodo
intercept():
public String intercept(ActionInvocation invocation){
:
return invocation.invoke();
}

RA-MA CAPTULO 8. STRUTS 2 261

PRCTICA 8.2. DETECCIN DE USUARIOS HABITUALES
Descripcin
La siguiente prctica que vamos a realizar consistir en una pequea
aplicacin que sea capaz de detectar si un usuario es habitual del sitio, es decir, lo
ha visitado con anterioridad, en cuyo caso se le dirigir a una pgina de bienvenida
personalizada que le mostrar un mensaje indicndole esta circunstancia.
Si el usuario no ha visitado nunca el sitio se le llevar a una pgina en la
que deber introducir un nombre de usuario que sirva para recordarle durante la
prxima visita que realice al sitio. La imagen de la figura 41 muestra las distintas
pginas involucradas en la aplicacin.









Fig. 41. Pginas de la aplicacin
Desarrollo
Para recordar a los usuarios la aplicacin utilizar una cookie en la que
almacenar el nombre de usuario introducido en la pgina de inicio. Cada vez que
un usuario entre en la aplicacin, un interceptor comprobar la existencia de esta
cookie, estableciendo en una propiedad de tipo boolean definida dentro de la clase
de accin si se trata de un usuario habitual (true) o de un nuevo usuario (false).
262 STRUTS RA-MA

En funcin del valor de esta propiedad la accin generar el resultado
apropiado. Esta accin, llamada comprobar, deber corresponder a la peticin de
inicio de la aplicacin (comprobar.action).
Una segunda accin llamada grabar se encargar de crear la cookie para
los usuarios que entran por primera vez en la aplicacin.
Listado
Seguidamente se presenta el cdigo de los distintos componentes que
forman esta aplicacin.
struts.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE st r ut s PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s Conf i gur at i on
2. 0/ / EN"
" ht t p: / / st r ut s. apache. or g/ dt ds/ st r ut s- 2. 0. dt d" >
<st r ut s>
<package name=" val i daci on" namespace=" / "
ext ends=" st r ut s- def aul t " >
<i nt er cept or s>
<! - - r egi st r o del i nt er cept or per sonal i zado- - >
<i nt er cept or name=" compr uebauser "
cl ass=" mi scl ases. User I nt er cept or " / >
</ i nt er cept or s>
<! - - acci n cor r espondi ent e a l a pet i ci n de i ni ci o- - >
<act i on name=" compr obar "
cl ass=" mi scl ases. Compr obar Act i on" >
<r esul t name=" si " >/ pages/ ok. j sp</ r esul t >
<r esul t name=" no" >/ pages/ l ogi n. ht ml </ r esul t >
<i nt er cept or - r ef name=" compr uebauser " / >
</ act i on>
<! - - acci n asoci ada a l a pet i ci n gr abar . act i on
gener ada desde l a pgi na l ogi n. ht ml - - >
<act i on name=" gr abar " cl ass=" mi scl ases. Gr abar Act i on" >
<r esul t name=" gr abado" >
/ pages/ bi enveni da. j sp
</ r esul t >
</ act i on>
</ package>
RA-MA CAPTULO 8. STRUTS 2 263

</ st r ut s>
UserInterceptor.java
package mi scl ases;

i mpor t com. opensymphony. xwor k2. *;
i mpor t com. opensymphony. xwor k2. i nt er cept or . *;
i mpor t or g. apache. st r ut s2. *;
i mpor t or g. apache. st r ut s2. i nt er cept or . *;
i mpor t or g. apache. st r ut s2. ut i l . *;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t j avax. ser vl et . *;
/ / cl ase cor r espondi ent e al i nt er cept or per sonal i zado
publ i c cl ass User I nt er cept or ext ends Abst r act I nt er cept or
i mpl ement s St r ut sSt at i cs{
publ i c St r i ng i nt er cept ( Act i onI nvocat i on i nvocat i on)
t hr ows Except i on {
Compr obar Act i on act i on =
( Compr obar Act i on) i nvocat i on. get Act i on( ) ;

/ / l a i nt er f az St r ut sSt at i cs cont i ene una ser i e de
/ / const ant es que pueden ser ut i l i zadas por el mt odo
/ / get ( ) de Act i onCont ext par a obt ener l os di st i nt os
/ / obj et os del cont ext o de l a apl i caci n
Act i onCont ext cont ext =
i nvocat i on. get I nvocat i onCont ext ( ) ;
Ht t pSer vl et Request r equest =
( Ht t pSer vl et Request ) cont ext . get ( HTTP_REQUEST) ;
Cooki e [ ] cooki es=r equest . get Cooki es( ) ;
i f ( cooki es ! = nul l ) {
f or ( i nt i =0; i < cooki es. l engt h; i ++) {
i f ( cooki es[ i ] . get Name( ) . equal s( " user " ) ) {
act i on. set Exi st e( t r ue) ;
act i on. set User ( cooki es[ i ] . get Val ue( ) ) ;
}
}
}
r et ur n i nvocat i on. i nvoke( ) ;
}
}
264 STRUTS RA-MA

ComprobarAction.java
package mi scl ases;

i mpor t or g. apache. st r ut s2. i nt er cept or . *;
i mpor t or g. apache. st r ut s2. ut i l . *;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t j avax. ser vl et . *;

publ i c cl ass Compr obar Act i on{
/ / pr opi edad que i ndi ca si el usuar i o es o no
/ / habi t ual
bool ean exi st e;
St r i ng user ;
publ i c St r i ng execut e( ) t hr ows Except i on {
i f ( exi st e)
r et ur n " si " ;
el se
r et ur n " no" ;
}
publ i c St r i ng get User ( ) {
r et ur n user ;
}
publ i c voi d set User ( St r i ng user ) {
t hi s. user =user ;
}
publ i c bool ean get Exi st e( ) {
r et ur n exi st e;
}
publ i c voi d set Exi st e( bool ean exi st e) {
t hi s. exi st e=exi st e;
}
}
GrabarAction.java
package mi scl ases;

i mpor t or g. apache. st r ut s2. i nt er cept or . *;
i mpor t or g. apache. st r ut s2. ut i l . *;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t j avax. ser vl et . *;
RA-MA CAPTULO 8. STRUTS 2 265

publ i c cl ass Gr abar Act i on i mpl ement s Ser vl et Request Awar e,
Ser vl et ResponseAwar e{
St r i ng user ;
Ht t pSer vl et Response r esponse;
publ i c St r i ng execut e( ) t hr ows Except i on {
/ / gener a l a cooki e par a r ecor dar al usuar i o
Cooki e ck=new Cooki e( " user " , user ) ;
ck. set MaxAge( 2000) ;
r esponse. addCooki e( ck) ;
r et ur n " gr abado" ;
}
publ i c St r i ng get User ( ) {
r et ur n user ;
}
publ i c voi d set Ser vl et Request (
Ht t pSer vl et Request r equest ) {
user =r equest . get Par amet er ( " user name" ) ;
}
publ i c voi d set Ser vl et Response(
Ht t pSer vl et Response r esponse) {
t hi s. r esponse=r esponse;
}
}
login.html
<ht ml >
<head>
<t i t l e>Logi n</ t i t l e>
</ head>
<body>
<br / ><br / ><br / ><br / >
<cent er >
<h1>For mul ar i o de Aut ent i caci n</ h1>
<f or mact i on=" gr abar . act i on" met hod=" post " >
<t abl e>
<t r ><t d>Usuar i o</ t d><t d><i nput t ype=" t ext "
name=" user name" / ></ t d></ t r >
<t r ><t d al i gn=" cent er " col span=" 2" >
<i nput t ype=" submi t " val ue=" Ent r ar " / ></ t d>
</ t r >
</ t abl e>
266 STRUTS RA-MA

</ f or m>
<cent er >
</ body>
</ ht ml >
bienvenida.jsp
<! - - pgi na par a nuevos usuar i os- - >
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<t i t l e>Bi enveni da</ t i t l e>
</ head>
<body>
<cent er >
<h1>Bi enveni do <i ><s: pr oper t y val ue=" user " / >
</ i > a mi p&aacut e; gi na</ h1>
</ cent er >
</ body>
</ ht ml >
ok.jsp
<! - - pgi na par a usuar i os habi t ual es- - >
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<t i t l e>Bi enveni da</ t i t l e>
</ head>
<body>
<cent er >
<h1>Sr . / a. <i ><s: pr oper t y val ue=" user " / ></ i >,
RA-MA CAPTULO 8. STRUTS 2 267

ust ed ya ha est ado aqu </ h1>
</ cent er >
</ body>
</ ht ml >
8.5 LA LIBRERA DE ACCIONES STRUTS-TAGS
En este punto vamos a analizar las principales acciones J SP que podemos
utilizar para la creacin de vistas en aplicaciones Struts 2, acciones que forman
parte de la librera struts-tags cuyas clases de implementacin se incluyen en el
archivo struts2-core-2.0.11.jar del paquete de distribucin de Struts 2.
Para incluir una referencia al archivo de librera struts-tags desde una
pgina J SP, habr que aadir la siguiente directiva taglib al principio de la misma,
siendo habitual utilizar como prefijo para acceder a sus acciones la letra s:
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
El conjunto de acciones J SP proporcionadas por Struts 2 puede dividirse en
tres grandes grupos:
Acciones de manipulacin de datos. En este grupo se incluyen
todas las acciones para la manipulacin y extraccin de datos de
aplicacin, como el acceso a las propiedades de un objeto Action o
el establecimiento de valores en variables J SP.
Acciones de control. Incluye las utilizadas para el control del flujo
de la aplicacin.
Acciones UI. Incluye acciones para la generacin de controles
grficos en formularios XHTML. Estos componentes encapsulan
adems toda la funcionalidad necesaria para que los datos
capturados por los mismos sean insertados, con la ayuda de uno de
los interceptores predefinidos de Struts 2, en las propiedades del
objeto Action que atender la peticin.
8.5.1 El stack de objetos
Antes de pasar a analizar las acciones de Struts 2 es conveniente introducir
el concepto de stack de objetos, conocido tambin como ValueStack, y comprender
su funcionamiento, ya que la mayora de los tags de Struts 2 realizan un acceso al
mismo para llevar a cabo su misin.
268 STRUTS RA-MA

El stack de objetos es una especie de pila donde se van acumulando los
distintos objetos utilizados en la aplicacin, como el objeto de accin que acaba de
ser ejecutado, los parmetros de la peticin o los objetos HTTP (application,
session y request).
Suele ser habitual que desde el interior de una pgina J SP los tags de Struts
2 necesiten acceder a alguna de las propiedades de los objetos del Stack. La
notacin utilizada para ello se basa en las llamadas expresiones OGNL (Object-
Graph Navigation Language).
El lenguaje OGNL es bastante simple; en el caso de querer acceder a una
propiedad de uno de los objetos del stack, bastar con indicar el nombre de la
propiedad a la que se quiere acceder en el atributo correspondiente de la accin.
Por ejemplo, si quisiramos acceder una propiedad llamada password, se
indicara directamente el nombre de la propiedad en el atributo value del tag
property:
<s:property value=password/>
En este caso se ira interrogando a los distintos objetos del stack por esta
propiedad, empezando por el que se encuentra en la posicin superior (ltimo
objeto utilizado) hasta el ms interno. En el momento en que se encuentre un
objeto que cuente con dicha propiedad se devolver su valor al punto de llamada.
En caso de que deseemos acceder al valor de la propiedad para un
determinado objeto del Stack, la expresin OGNL a utilizar debe tener el siguiente
formato:
#objeto.propiedad
Por ejemplo, para recuperar la propiedad password de un objeto
identificado como user1 sera:
<s: pr oper t y val ue=" #user 1. passwor d" / >
As mismo, los atributos value de las acciones Struts 2 tambin admiten
expresiones EL, las cuales forman parte del J ava Enterprise, y cuya sintaxis se
detalla en el Apndice A del libro. Una expresin EL debe indicarse entre los
smbolos ${ y }.
Por ejemplo, la siguiente instruccin recupera la propiedad password
existente en un objeto identificado como user1que se encuentra almacenado en un
atributo de sesin:
RA-MA CAPTULO 8. STRUTS 2 269

<s: pr oper t y val ue=" ${sessi onScope[ ' user 1' ] . passwor d}" / >
8.5.2 Acciones de manipulacin de datos
Seguidamente pasaremos a analizar las principales acciones que se
incluyen en este grupo.
8.5.2.1 BEAN
Realiza la instanciacin de una clase de tipo J avaBean. Los atributos
soportados por esta accin son:
name. Nombre cualificado de la clase que se va a instanciar.
id. Identificador de la variable donde se almacenar la referencia a
la instancia.
8.5.2.2 PARAM
Se utiliza para establecer parmetros en otros tags, como por ejemplo las
propiedades de un J avaBean creado con la accin <s:bean>. Mediante su atributo
name se indica el nombre del parmetro, incluyendo en el cuerpo del elemento el
valor que se quiere asignar.
El siguiente bloque de acciones de ejemplo creara una instancia del bean
Mensaje y le asignara valores a sus propiedades remite, destinatario y texto:
<s: bean name=" j avabeans. Mensaj e" i d=" mensa" >
<s: par amname=" r emi t e" >pr of e</ s: par am>
<s: par amname=" dest i nat ar i o" >mar t a</ s: par am>
<s: par amname=" t ext o" >hol a</ s: par am>
</ s: bean>
8.5.2.3 PROPERTY
Recupera el valor de una determinada propiedad. Su principal atributo es
value, el cual, como hemos visto anteriormente, debe contener el nombre de la
propiedad que se quiere recuperar. El elemento <s:property>es aplicado sobre los
objetos del stack, empezando desde el ms externo hasta el ms interno.
Si se emplea property sin especificar su atributo value, se recuperara el
ltimo elemento depositado en el stack:
<! - - ext r ae el l t i mo el ement o deposi t ado en el st ack- - >
270 STRUTS RA-MA

<s: pr oper t y/ >
8.5.2.4 PUSH
Este elemento aade un determinado objeto al stack. Mediante su atributo
value se indica el objeto a aadir.
El siguiente ejemplo mostrara en la pgina el valor de la propiedad
destino del objeto mensa:
<s: push val ue=" mensa" >
<s: pr oper t y val ue=" dest i no" / >
</ s: push>
8.5.2.5 SET
Asigna un valor a una variable y la deposita en un determinado mbito. Sus
atributos son:
name. Nombre asignado a la variable.
value. Valor asignado a la variable.
scope. mbito de la variable. Su valor puede ser action, page,
request, session o application, siendo action el valor
predeterminado.
Despus de establecer la variable sta queda en el stack de objetos. El
siguiente ejemplo asigna una cadena de texto a una variable y a continuacin
muestra su valor:
<s: set name=" var i abl e" val ue=" ${' hol a' }" / >
val or de l a var i abl e: <h1><s: pr oper t y
val ue=" #var i abl e" def aul t =" def ect o" / ></ h1>
Obsrvese cmo el valor de la variable aparece encerrado dentro de una
expresin.
8.5.3 Acciones de control
Veamos a continuacin las principales acciones que se incluyen en este
grupo.
RA-MA CAPTULO 8. STRUTS 2 271

8.5.3.1 IF
Evala el cuerpo de la accin si se cumple la condicin establecida en su
atributo test. Dicha condicin debe dar por tanto como resultado un tipo boolean.
Al ejecutar el siguiente bloque de sentencias se mostrar el texto usuario
administrador en la pgina de respuesta:
<s: set name=" user " val ue=" ${' admi ni st r ador ' }" / >
<s: i f t est =" ${#user ==' admi ni st r ador ' }" >
<h1>usuar i o <s: pr oper t y val ue=" #user " / ></ h1>
</ s: i f >
Una accin <s:if>puede ir seguida de una o varias acciones <s:elseif>que
comprueben otras condiciones si la condicin de <s:if>resulta false, y de una
accin <s:else> cuyo cuerpo ser evaluado si no se cumple ninguna de las
condiciones <s:if>ni <s:elseif>:
<s: i f t est =" condi ci on1" >
<! - - eval uado si condi ci on1 es true- - >
</ s: i f >
<s: el sei f t est =" condi ci on2" >
<! - - eval uado si condi ci on1 es f al se y
condi ci on2 es t r ue- - >
</ s: el sei f >
<s: el se>
<! - - eval uado si condi ci on1 y
condi ci on2 son ambas f al se- - >
</ s: el se>
8.5.3.2 ITERATOR
La accin iterator se utiliza para recorrer una coleccin de tipo Collection o
Iterator. Dispone de los siguientes atributos:
value. Coleccin sobre la que se realizar la iteracin.
id. Variable que contendr una referencia al elemento de la
coleccin correspondiente a la iteracin actual.
Por ejemplo, si ListaTareas es una clase de tipo coleccin con una
propiedad agregar, cuyo mtodo setAgregar() realiza la insercin de un nuevo
elemento en la coleccin, el siguiente grupo de sentencias aadira tres tareas a la
coleccin para despus recorrerla y mostrar la lista de tareas en la pgina, siendo
272 STRUTS RA-MA

tareas la propiedad de la clase ListaTareas que da acceso a la coleccin de
elementos:
<s: bean name=" cl ases. Li st aTar eas" var =" t ar ea" / >
<s: par amname=" agr egar " >sumar </ s: par am>
<s: par amname=" agr egar " >r est ar </ s: par am>
<s: par amname=" agr egar " >mul t i pl i car </ s: par am>
</ s: bean>
<s: i t er at or i d=" act ual " val ue=" #t ar ea. t ar eas" >
<! - - muest r a el val or act ual del i t er ador - - >
<s: pr oper t y val ue=" #act ual " / >
</ s: i t er at or >
Si lo nico que queremos hacer dentro del iterator es extraer el valor de la
iteracin actual, no es necesario indicar el atributo id en el tag. El motivo es que,
cuando se recorre la coleccin, Struts2 deposita el valor actual en la parte superior
del stack, pudindose recuperar directamente dicho valor utilizando el elemento
property sin atributos.
Segn lo indicado, el iterator anterior podra implementarse tambin de la
siguiente forma:
<s: i t er at or val ue=" #t ar ea. t ar eas" >
<! - - muest r a el val or act ual del i t er ador - - >
<s: pr oper t y/ >
</ s: i t er at or >

8.5.4 Acciones UI
Las acciones UI de struts 2 facilitan la construccin de las interfaces
grficas de una aplicacin Web, simplificando las tareas de captura de datos de
usuario y su validacin.
Aunque muchos de los tags UI de struts se corresponden con un
componente grfico XHTML, el cdigo embebido dentro de estos tags realiza una
serie de funciones para el programador que, en caso de haber utilizado elementos
simples XHTML, habran tenido que ser definidos mediante cdigo. Entre estas
funciones estn:
Vinculacin de los datos de los controles a propiedades de un
action.
RA-MA CAPTULO 8. STRUTS 2 273

Generacin de variables en el ValueStack con los datos de los
controles.
Facilitar la validacin y conversin de los valores suministrados en
los controles.
Formateado de los controles. Los UI tags de Struts 2 generan
etiquetas de marcado adicionales para dar el formato adecuado de
presentacin a los controles.
Seguidamente, estudiaremos los diferentes tags proporcionados por Struts
2 para la construccin de formularios de captura de datos.
8.5.4.1 FORM
Es el tag ms importante. Genera una etiqueta XHTML de tipo <form>que
nos permitir definir el action que procesar los datos recogidos por los controles
del formulario.
Esta accin incluye la funcionalidad necesaria para evitar que el contenido
de la pgina sea refrescado una vez que se han enviado los datos y, por tanto, se
mantengan los valores de los controles en caso de que vuelva a mostrarse la pgina
al usuario. Entre sus atributos ms importantes estn:
name. Nombre asociado al elemento <form>XHTML.
method. Mtodo de envo de los datos.
action. Nombre del objeto Action que capturar la peticin. Si no
se utiliza este atributo la peticin ser procesada por el objeto
Action actual.
namespace. Namespace en el que se encuentra la definicin de la
accin. Si no se utiliza este atributo, se asume que se trata del
namespace actual.
8.5.4.2 TEXTFIELD
Genera una caja de texto de una lnea. Como atributos ms destacados
tenemos:
name. Nombre de la propiedad del objeto Action en la que se
volcar el contenido del control. Con ayuda de uno de los
274 STRUTS RA-MA

interceptores predefinidos de Struts 2, la informacin recogida en
los campos del formulario es volcada directamente en las
propiedades del objeto Action indicado en los elementos
<s:form>, sin necesidad de incluir ninguna instruccin de cdigo
ni elementos de configuracin adicionales.
value. Valor de inicializacin del control.
readonly. Si su valor es true, el usuario no podr modificar el
contenido del campo de texto.
label. Texto que aparecer al lado del control. Dicho texto se
incluir dentro de un elemento XHTML de tipo <label>. Adems
de ello, de forma predeterminada el formulario aplicar sobre este
componente un formato de tipo fila de tabla, incluyendo el label en
una celda y el componente de texto en otra.
Por ejemplo, si definimos el siguiente formulario en una pgina
J SP:
<s: f or mact i on=" pr oceso. act i on" >
<s: t ext f i el d name=" user " l abel =" usuar i o" / >
<s: submi t val ue=" ent r ar " / >
</ s: f or m>
el bloque equivalente XHTML que se generar al procesar la
pgina ser similar al siguiente:
<f or mi d=" pr oceso" act i on=" pr oceso. act i on"
met hod=" post " >
<t abl e cl ass=" wwFor mTabl e" >
<t r >
<t d cl ass=" t dLabel " ><l abel f or =" pr oceso_user "
cl ass=" l abel " >usuar i o: </ l abel ></ t d>
<t d>
<i nput t ype=" t ext " name=" user " val ue=" "
i d=" pr oceso_user " / ></ t d></ t r >
<t r >
<t d col span=" 2" ><di v al i gn=" r i ght " >
<i nput t ype=" submi t " i d=" pr oceso_0"
val ue=" Ent r ar " / >
</ di v></ t d>
</ t r >
RA-MA CAPTULO 8. STRUTS 2 275

</ t abl e>
</ f or m>

8.5.4.3 PASSWORD
Genera una caja de texto de tipo password. Adems de los atributos name,
label y value, cuyo significado es el mismo que en el caso de la accin
<s:textfield>, este control dispone del atributo showPassword de tipo boolean,
mediante el que podemos indicar si queremos inicializar el control con el valor del
ValueStack, en caso de que exista una propiedad con el mismo nombre que el
control, o no.
8.5.4.4 TEXTAREA
Genera una caja de texto multilnea. Los atributos name, readonly y value
tienen el mismo significado que en los controles anteriores, aunque dispone adems
de los siguientes atributos para establecer el tamao del control:
cols. Ancho del control en nmero de lneas.
rows. Alto del control en nmero de filas.
8.5.4.5 SUBMIT
Genera un botn de tipo submit para realizar la peticin y envo del
formulario. Mediante su atributo value se indica el texto que se quiere mostrar en el
control.
Para ver la potencia de estos elementos grficos volvamos de nuevo a la
prctica 8.1. En ella utilizbamos un formulario XHTML para recoger los
credenciales del usuario y enviarlos a un objeto de accin, cuya clase deba
implementar una de las interfaces asociadas al interceptor ServletConfigInterceptor
para poder tener acceso al objeto HttpServletRequest y recuperar as los datos del
formulario.
Si en vez de una pgina XHTML hubiramos utilizado una pgina J SP con
los controles Struts 2 indicados anteriormente, nada de esto habra sido necesario
puesto que los contenidos de los campos de texto se pueden volcar directamente
en las correspondientes propiedades del objeto Action. Con esta solucin, la
pgina J SP de inicio quedara:
<%@page cont ent Type=" t ext / ht ml ; char set =UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
276 STRUTS RA-MA

<ht ml >
<head>
<t i t l e>Val i daci n</ t i t l e>
</ head>
<body>
<!--siempre tiene que incluirse la extensin .action en
la URL. En este caso, el tag form de Struts pone la extensin
automticamente a la cadena incluida en action-->

<s: f or mact i on=" Logi n" >
<t abl e>
<t r ><t d>Usuar i o</ t d><t d>
<s: t ext f i el d name=" user " / ></ t d></ t r >
<t r ><t d>Passwor d</ t d><t d>
<s: passwor d name=" pwd" / ></ t d></ t r >
<t r ><t d col span=" 2" >
<s: submi t / ></ t d></ t r >
</ s: f or m>
</ body>
</ ht ml >
Por su parte, la clase de accin Login quedara ahora algo ms
simplificada:
package mi scl ases;

i mpor t or g. apache. st r ut s2. i nt er cept or . *;
i mpor t or g. apache. st r ut s2. ut i l . *;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t j avax. ser vl et . *;
/ / no es necesar i o i mpl ement ar Ser vl et Request Awar e
publ i c cl ass Val i dar i mpl ement s Ser vl et Cont ext Awar e{
St r i ng pwd;
St r i ng user ;
Ser vl et Cont ext cont ext ;
publ i c St r i ng execut e( ) t hr ows Except i on {
St r i ng dr i ver =cont ext . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=cont ext . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=
new Gest i onCl i ent es( dr i ver , cadenaCon) ;
i f ( gc. val i dar ( user , pwd) )
r et ur n " ok" ;
RA-MA CAPTULO 8. STRUTS 2 277

el se
r et ur n " er r or " ;
}
publ i c St r i ng get User ( ) {
r et ur n user ;
}
publ i c St r i ng get Pwd( ) {
r et ur n pwd;
}
publ i c voi d set Ser vl et Cont ext ( Ser vl et Cont ext cont ext ) {
t hi s. cont ext =cont ext ;
}
}
8.5.4.6 RADIO
Con esta accin es posible generar una lista de elementos XHTML de tipo
radio. Su propiedad ms importante es list, la cual indicar el objeto de tipo lista
cuyos datos sern utilizados para la generacin de los controles.
Por ejemplo, supongamos que tenemos un objeto bean identificado como
calendario que dispone de una propiedad das de tipo ArrayList de cadenas de
caracteres. Por otro lado, el bean cuanta con una propiedad agregar cuyo mtodo
asociado setAgregar() se encarga de almacenar en la lista la cadena recibida como
parmetro. Con esta situacin, el siguiente bloque de sentencias generar cinco
botones de radio, cada uno de los cuales tendr como texto asociado el nombre de
un da:
<ht ml >
<body>
<s: bean name=" cal endar i o" i d=" di act ual " / >
<s: par amname=" agr egar " >l unes</ s: par am>
<s: par amname=" agr egar " >mar t es</ s: par am>
<s: par amname=" agr egar " >mi r col es</ s: par am>
<s: par amname=" agr egar " >j ueves</ s: par am>
<s: par amname=" agr egar " >vi er nes</ s: par am>
</ s: bean>
<h1>Di as l abor abl es: </ h1>
<s: r adi o name=" semana" l i st =" #cal endar i o. di as" / >
</ body>
</ ht ml >
278 STRUTS RA-MA

En la imagen de la figura 42 se presenta el aspecto de la pgina generada a
partir del cdigo anterior.







Fig. 42. Lista de botones con los das de la semana
Como podemos comprobar, el atributo list del componente se asocia a la
propiedad de tipo lista del bean; por su parte, el atributo name del tag determina el
nombre de la propiedad del objeto Action en la que se volcar el valor del atributo
value del botn seleccionado.
En el ejemplo anterior, dado que se trata de una coleccin de cadenas de
caracteres, el nombre del da de la semana se utiliza tanto como texto a mostrar en
el componente como valor asociado al mismo, sin embargo, si la coleccin fuera de
cualquier otro tipo de objeto J avaBean, sera necesario especificar los siguientes
atributos adicionales de <s:radio>:
listKey. Nombre de la propiedad del bean que se utilizar como
valor asociado a cada botn de radio. En caso de colecciones de
tipo Map, no ser necesario utilizar esta propiedad, puesto que la
clave de la coleccin ser utilizada directamente como valor
asociado
listValue. Nombre de la propiedad del bean que se utilizar como
texto a mostrar con cada botn de radio. En caso de colecciones de
tipo Map, no ser necesario utilizar esta propiedad, utilizndose el
valor de cada elemento de la coleccin como texto del radio
button.
RA-MA CAPTULO 8. STRUTS 2 279

8.5.4.7 CHECKBOX
Genera un elemento XHTML de tipo checkbox. Sus principales atributos
son:
name. Nombre de la propiedad del objeto Action donde se
almacenar el valor del atributo fieldValue de la accin.
fieldValue. Value asociado al elemento XHTML correspondiente.
8.5.4.8 CHECKBOXLIST
Es similar a <s:radio>slo que en el caso de <s:checkboxlist>se generar
una lista de casillas de verificacin. Sus atributos son los mismos que los del tag
<s:radio>, teniendo en cuenta que la propiedad del objeto Action especificada en
el atributo name deber ser de tipo array o list para poder almacenar el conjunto
de valores seleccionados.
8.5.4.9 SELECT
Mediante esta accin se genera una lista de seleccin de elementos, donde
cada elemento es codificado en la pgina mediante una etiqueta XHTML de tipo
<option>. Sus principales atributos son:
name. Nombre de la propiedad del objeto Action donde ser
volcado el valor del elemento seleccionado.
list. Indica el objeto lista (List o Map) que contiene los datos con
los que se rellenar el control.
listKey y listValue. El significado de estas propiedades es el
mismo que en el caso de los otros componentes de coleccin
<s:radio>y <s:checkboxlist>.
headerValue. Texto que aparecer como primer elemento de la
lista. Resulta til en aquellos casos en que no queramos que
aparezca ningn elemento de la lista preseleccionado.
headerKey. Clave (value) asociada al primer elemento de la lista
especificado en headerValue.
El siguiente ejemplo genera una lista con los das de la semana. Como se
puede observar, la lista es generada mediante una expresin en el propio atributo
list, indicando la clave y texto a visualizar para cada elemento:
280 STRUTS RA-MA

<s: f or m>
<s: sel ect name=" semana"
header Key=" 0"
header Val ue=" - - Sel ecci one d a - - "
l i st =" #{' 01' : ' l unes' , ' 02' : ' mar t es' , ' 03' : ' mi r col es' ,
' 04' : ' j ueves' , ' 05' : ' vi er nes' ,
' 06' : ' sbado' , ' 07' : ' domi ngo' }" / >
</ s: f or m>
Si a la hora de definir un select, los elementos que componen la lista son
conocidos durante la fase de diseo, cada uno de stos puede ser especificado.
PRCTICA 8.3. SELECCIN MLTIPLE DE TEMAS
Descripcin
Vamos a desarrollar una sencilla prctica como ejemplo de utilizacin de
los controles de seleccin, ms concretamente, del checkboxlist.
Tras pulsar un enlace existente en una pgina de inicio, se acceder a una
pgina que nos mostrar una serie de temas entre los que podremos elegir varios de
ellos, para lo que se utilizar un grupo de checkbox. Una vez seleccionados los
temas y despus de pulsar el botn Entrar, se mostrar una nueva pgina que
simplemente nos mostrar los cdigos de los temas seleccionados.
La figura 43 ilustra el flujo de pginas de la aplicacin.







Fig. 43. Flujo de pginas de la aplicacin
RA-MA CAPTULO 8. STRUTS 2 281

Desarrollo
Para el desarrollo de esta aplicacin, crearemos un bean llamado Tema que
encapsule los dos datos que caracterizarn a esta entidad: el cdigo de tema y el
nombre. La clase Action llamada Tematica, asociada a la pulsacin del enlace de la
pgina de inicio, ser la encargada de generar la coleccin de temas y de
depositarla en una propiedad del objeto, a fin de que sea accesible para el
componente checkboxlist incluido en la pgina temas.jsp.
Los cdigos de los temas seleccionados sern cargados en un ArrayList de
tipo Integer por parte del objeto de accin Selecciones, asociado a la pulsacin del
botn Entrar. El contenido de esta coleccin ser mostrado posteriormente por la
pgina seleccion.jsp.
Listado
Los siguientes listados de cdigo corresponden a los diferentes
componentes de la aplicacin
Tema.java
package beans;

publ i c cl ass Tema {
pr i vat e i nt codi go;
pr i vat e St r i ng t ema;
publ i c Tema( ) {
}
publ i c Tema( i nt codi go, St r i ng t ema) {
t hi s. codi go = codi go;
t hi s. t ema = t ema;
}
publ i c i nt get Codi go( ) {
r et ur n codi go;
}
publ i c voi d set Codi go( i nt codi go) {
t hi s. codi go = codi go;
}
publ i c St r i ng get Tema( ) {
r et ur n t ema;
}
publ i c voi d set Tema( St r i ng t ema) {
282 STRUTS RA-MA

t hi s. t ema = t ema;
}
}

Tematica.java
package acci ones;
i mpor t j ava. ut i l . *;
i mpor t beans. Tema;
publ i c cl ass Temat i ca {
pr i vat e Ar r ayLi st <Tema> t emas;
publ i c Ar r ayLi st <Tema> get Temas( ) {
r et ur n t emas;
}
publ i c voi d set Temas( Ar r ayLi st <Tema> t emas) {
t hi s. t emas = t emas;
}
publ i c St r i ng execut e( ) t hr ows Except i on{
t emas=new Ar r ayLi st <Tema>( ) ;
t emas. add( new Tema( 3345, " ci enci as" ) ) ;
t emas. add( new Tema( 12432, " pol i t i ca" ) ) ;
t emas. add( new Tema( 98371, " ci ne" ) ) ;
t emas. add( new Tema( 60092, " ocul t i smo" ) ) ;
r et ur n " compl et ado" ;
}
}

Selecciones.java
package acci ones;
i mpor t j ava. ut i l . *;

publ i c cl ass Sel ecci ones {
pr i vat e Ar r ayLi st <I nt eger > sel ecci onados;
publ i c Ar r ayLi st <I nt eger > get Sel ecci onados( ) {
r et ur n sel ecci onados;
}
publ i c voi d set Sel ecci onados(
Ar r ayLi st <I nt eger > sel ecci onados) {
t hi s. sel ecci onados = sel ecci onados;
}
RA-MA CAPTULO 8. STRUTS 2 283

publ i c St r i ng execut e( ) t hr ows Except i on{
r et ur n " sel ecci on" ;
}
}

index.jsp
<%@page cont ent Type=" t ext / ht ml " pageEncodi ng=" UTF- 8" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD
HTML 4. 01 Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type"
cont ent =" t ext / ht ml ; char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1><a hr ef =" t emat i ca. act i on" >
Most r ar l os t emas</ a></ h1>
</ cent er >
</ body>
</ ht ml >

temas.jsp
<%@page cont ent Type=" t ext / ht ml " pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD
HTML 4. 01 Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type"
cont ent =" t ext / ht ml ; char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1>Sel ecci n de t emas</ h1>
284 STRUTS RA-MA

<s: f or mact i on=" sel ecci ones. act i on" met hod=" post " >
<s: checkboxl i st name=" sel ecci onados"
l i st =" t emas" l i st Key=" codi go" l i st Val ue=" t ema" / >
<s: submi t val ue=" Ent r ar " / >
</ s: f or m>
</ cent er >
</ body>
</ ht ml >

seleccin.jsp
<%@page cont ent Type=" t ext / ht ml " pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD
HTML 4. 01 Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >

<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type"
cont ent =" t ext / ht ml ; char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<cent er >
<h1>Los t emas el egi dos son: </ h1>
<s: i t er at or val ue=" sel ecci onados" >
<s: pr oper t y/ ><br / >
</ s: i t er at or >
</ cent er >
</ body>
</ ht ml >

struts.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE st r ut s PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s Conf i gur at i on
2. 0/ / EN"
" ht t p: / / st r ut s. apache. or g/ dt ds/ st r ut s- 2. 0. dt d" >
<st r ut s>
<const ant name=" st r ut s. enabl e. Dynami cMet hodI nvocat i on"
RA-MA CAPTULO 8. STRUTS 2 285

val ue=" f al se" / >
<const ant name=" st r ut s. devMode" val ue=" f al se" / >
<package name=" t emas_l i br os"
namespace=" / " ext ends=" st r ut s- def aul t " >
<act i on name=" t emat i ca" cl ass=" acci ones. Temat i ca" >
<r esul t name=" compl et ado" >/ t emas. j sp</ r esul t >
</ act i on>
<act i on name=" sel ecci ones"
cl ass=" acci ones. Sel ecci ones" >
<r esul t name=" sel ecci on" >/ sel ecci on. j sp</ r esul t >
</ act i on>
</ package>
</ st r ut s>

web.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<web- app ver si on=" 2. 5"
xml ns=" t t p: / / j ava. sun. com/ xml / ns/ j avaee"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSchema- i nst ance"
xsi : schemaLocat i on=" ht t p: / / j ava. sun. com/ xml / ns/ j avaee
ht t p: / / j ava. sun. com/ xml / ns/ j avaee/ web- app_2_5. xsd" >
<sessi on- conf i g>
<sessi on- t i meout >
30
</ sessi on- t i meout >
</ sessi on- conf i g>
<f i l t er >
<f i l t er - name>st r ut s2</ f i l t er - name>
<f i l t er - cl ass>or g. apache. st r ut s2. di spat cher .
Fi l t er Di spat cher </ f i l t er - cl ass>
</ f i l t er >
<f i l t er - mappi ng>
<f i l t er - name>st r ut s2</ f i l t er - name>
<ur l - pat t er n>/ *</ ur l - pat t er n>
</ f i l t er - mappi ng>
<wel come- f i l e- l i st >
<wel come- f i l e>i ndex. j sp</ wel come- f i l e>
</ wel come- f i l e- l i st >
</ web- app>
286 STRUTS RA-MA

8.5.4.10 ACTIONERROR
Aunque no se trata de un control grfico, la accin <s:actionerror/>se
encuentra dentro del grupo de acciones grficas de Struts 2. Su cometido es mostrar
los mensajes de error en caso de que hayan sido generados desde la accin.
El mtodo addActionError(String mensajerror), incluido en la clase
com.opensymphony.xwork2.ActionSupport, permite aadir fcilmente un mensaje
de error desde la clase de accin. Tan slo hay que crear la clase de accin como
una subclase de ActionSupport e invocar a este mtodo en el momento en que se
considere que hay que aadir un mensaje de error.
8.6 VALIDADORES
Al igual que sucede en Struts 1.x, Struts 2 cuenta con la posibilidad de
llevar a cabo la validacin de los datos de usuario de manera declarativa. En este
sentido, Struts 2 dispone de una serie de validadores predefinidos que permiten
realizar esta tarea sin que para ello el programador tenga que escribir una sola
instruccin de cdigo J ava.
8.6.1 Validadores predefinidos
El paquete de distribucin de Struts 2 cuenta con una serie de validadores
predefinidos, incluidos en el archivo xwork-2.0.4.jar (si utiliza otra versin de
Struts 2 los nmeros que aparecen en el nombre del archivo pueden ser diferentes).
Para que una aplicacin pueda hacer uso de estos validadores es necesario
que estn declarados en un documento XML (validation.xml), cuya ubicacin est
accesible desde el classpath de la aplicacin. He aqu el aspecto que debe tener este
documento:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<! DOCTYPE val i dat or s PUBLI C
" - / / OpenSymphony Gr oup/ / XWor k Val i dat or
Conf i g 1. 0/ / EN"
" ht t p: / / www. opensymphony. com/ xwor k/ xwor k- val i dat or -
conf i g- 1. 0. dt d" >
<val i dat or s>
<val i dat or name=" r equi r ed" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. Requi r edFi el dVal i dat or " / >
<val i dat or name=" r equi r edst r i ng" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. Requi r edSt r i ngVal i dat or " / >
RA-MA CAPTULO 8. STRUTS 2 287

<val i dat or name=" i nt " cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. I nt RangeFi el dVal i dat or " / >
<val i dat or name=" doubl e" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. Doubl eRangeFi el dVal i dat or " / >
<val i dat or name=" dat e" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. Dat eRangeFi el dVal i dat or " / >
<val i dat or name=" expr essi on" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. Expr essi onVal i dat or " / >
<val i dat or name=" f i el dexpr essi on" cl ass=" com.
opensymphony. xwor k2. val i dat or .
val i dat or s. Fi el dExpr essi onVal i dat or " / >
<val i dat or name=" emai l " cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. Emai l Val i dat or " / >
<val i dat or name=" ur l " cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. URLVal i dat or " / >
<val i dat or name=" vi si t or " cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. Vi si t or Fi el dVal i dat or " / >
<val i dat or name=" conver si on" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s.
Conver si onEr r or Fi el dVal i dat or " / >
<val i dat or name=" st r i ngl engt h" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s.
St r i ngLengt hFi el dVal i dat or " / >
<val i dat or name=" r egex" cl ass=" com. opensymphony.
xwor k2. val i dat or . val i dat or s. RegexFi el dVal i dat or " / >
</ val i dat or s>
El archivo xwork-2.0.4.jar tambin incluye este documento XML, por lo
que no ser necesario tener que generarlo manualmente. Por otro lado, al estar
incluido en el directorio WEB-INF\lib de la aplicacin no ser necesario realizar
ninguna operacin adicional en la variable de entorno classpath.
Adems de declarar los validadores, es necesario activar el interceptor
Struts encargado de poner en marcha el proceso de validacin automtica:
<i nt er cept or name=" val i dat or " cl ass=" com. opensymphony.
xwor k2. val i dat or . Val i dat i onI nt er cept or " / >
La anterior operacin tampoco es necesaria que la realicemos
explcitamente en nuestro struts.xml, puesto que el documento de configuracin
por defecto ya incluye el registro de este validador adems de aadirlo al stack
de validadores por defecto.
288 STRUTS RA-MA

8.6.2 Utilizacin de validadores en una aplicacin
La utilizacin de estos validadores en una aplicacin Struts 2 es una tarea
tremendamente sencilla: tan slo tendremos que crear un archivo XML en el que
asociaremos las reglas de validacin con los campos del objeto Action a los que se
las queramos aplicar.
Este archivo XML tendr que nombrarse siguiendo el siguiente formato:
claseaccion-validation.xml
donde claseaccion se corresponder con el nombre de la clase a la que pertenece el
objeto Action cuyos campos se quieren validar.
Por ejemplo, supongamos que tenemos una clase de accin llamada
Login.class, similar a la utilizada en una de las prcticas analizadas en este
Captulo, y que se encarga de comprobar los credenciales de un usuario
suministrados desde una pgina de login:
package mi scl ases;
i mpor t com. opensymphony. xwor k2. Act i onSuppor t ;

publ i c cl ass Logi n ext ends Act i onSuppor t {
pr i vat e St r i ng user name;
pr i vat e St r i ng passwor d;
publ i c St r i ng execut e( ) t hr ows Except i on {
i f ( get Passwor d( ) . equal s( " admi n" ) )
r et ur n SUCCESS;
el se
r et ur n ERROR;
}

publ i c voi d set User name( St r i ng us) {
t hi s. user name = us;
}
publ i c St r i ng get User name( ) {
r et ur n t hi s. user name;
}
publ i c voi d set Passwor d( St r i ng pwd) {
t hi s. passwor d = pwd;
}
publ i c St r i ng get Passwor d( ) {
RA-MA CAPTULO 8. STRUTS 2 289

r et ur n t hi s. passwor d;
}
}
La clase comprueba el campo password y si su valor es igual a admin,
devolver una de las constantes predefinidas en la interfaz ActionSupport, que ser
interpretada como validacin correcta.
Si quisiramos aadir una regla de validacin para forzar la entrada
obligatoria de datos en ambos campos, tendramos que crear un archivo llamado
Login-validation.xml en el que asociaramos cada regla con cada campo, segn se
indica en el siguiente listado:
<! DOCTYPE val i dat or s PUBLI C
" - / / OpenSymphony Gr oup/ / XWor k Val i dat or 1. 0. 2/ / EN"
" ht t p: / / www. opensymphony. com/ xwor k/ xwor k- val i dat or -
1. 0. 2. dt d" >

<val i dat or s>
<f i el d name=" user name" >
<f i el d- val i dat or t ype=" r equi r edst r i ng" >
<message>Debes i nt r oduci r un usuar i o</ message>
</ f i el d- val i dat or >
</ f i el d>
<f i el d name=" passwor d" >
<f i el d- val i dat or t ype=" r equi r edst r i ng" >
<message>Debes i nt r oduci r un passwor d</ message>
</ f i el d- val i dat or >
</ f i el d>
</ val i dat or s>

Es importante indicar que este archivo debe estar situado en el mismo
directorio en que se encuentre el archivo .class correspondiente a la clase de
accin.
Como vemos en el listado anterior, para cada campo aadiremos un
elemento <field>en el que se indicar mediante el subelemento <field-validator>
la regla que se quiere aplicar a travs de su atributo type. As pues, para cada
elemento <field>habr que aadir tantos <field-validator>como reglas se quieran
aplicar al campo.
290 STRUTS RA-MA

Cada regla llevar su propio mensaje de error asociado a travs del
elemento <message>aunque al igual que en el caso de Struts 1, los mensajes de
error pueden estar definidos en un archivo ApplicationResources.properties con sus
correspondientes claves. En este caso, el elemento message simplemente deber
indicar la clave del mensaje de error:
<f i el d- val i dat or t ype=" r equi r edst r i ng" >
<message key=" passwor d. nul o" / >
</ f i el d- val i dat or >
Para forzar a que el usuario sea redireccionado de nuevo a la pgina de
login en caso de incumplirse las reglas de validacin, simplemente habra que
aadir una entrada <result>cuyo valor de atributo name sea input en el archivo
de configuracin struts.xml:
<act i on name=" Logi n" cl ass=" mi scl ases. Logi n" >
<r esul t >/ pages/ ok. j sp</ r esul t >
<r esul t name=" er r or " >/ pages/ er r or . j sp</ r esul t >
<result name="input">/pages/login.jsp</result>
</ act i on>
Para poder mostrar los mensajes de error en la pgina de login cuando el
usuario sea redireccionado a ella al incumplir las reglas de validacin, ser
necesario incluir el elemento <s:actionerror/>en la pgina.
Si queremos que la validacin se realice en cliente, tan slo ser necesario
aadir el atributo validate con el valor true al elemento <s:form>en el que se
incluyen los elementos grficos para la captura de los datos:
<s: f or mact i on=" Logi n" met hod=" post " val i dat e=" t r ue" >
:
</ s: f or m>
La inclusin de este atributo en el formulario har que se genere todo el
J avaScript necesario para realizar la comprobacin de los datos en cliente,
incluyendo los cuadros de dilogo que se mostrarn al usuario con los mensajes de
error cuando el resultado de la validacin sea negativo.
Otros tipos de validadores que se pueden especificar en field-validator,
adems de requiredstring, son:
email. Comprueba que el valor introducido en el campo
corresponda con una direccin de correo vlida.
RA-MA CAPTULO 8. STRUTS 2 291

int. Comprueba que el valor introducido en el campo sea un
nmero entero comprendido entre dos valores dados. Dichos
valores tendrn que ser suministrados como parmetros de field-
validator a travs del elemento param. Por ejemplo, para
comprobar que el valor de un campo llamado cdigo est
comprendido entre 10 y 20 definiramos el siguiente validador
sobre el campo:
<f i el d name=" codi go" >
<f i el d- val i dat or t ype=" i nt " >
<par amname=" mi n" >10</ par am>
<par amname=" max" >20</ par am>
<message>f uer a de r ango</ message>
</ f i el d- val i dat or >
</ f i el d>

8.6.3 Validacin mediante Anotaciones
Una de las novedades introducidas en Struts 2 respecto a Struts 1 es la
posibilidad de utilizar anotaciones para simplificar las tareas de configuracin en
una aplicacin, eliminando as la necesidad de utilizar ficheros de
configuracin XML para realizar esas funciones.
Por ejemplo, en las aplicaciones que hacen uso de validadores, los archivos
de configuracin de tipo ClaseAccion-validation.xml pueden ser sustituidos por
anotaciones que sern introducidas en la propia clase de accin.
Para este caso concreto de aplicaciones basadas en validadores, la
utilizacin de anotaciones requiere la realizacin de dos operaciones previas
durante la implementacin de la clase Action:
Que la clase herede ActionSupport. La clase ActionSupport, que
se encuentra en el paquete com.opensymphony.xwork2,
proporciona una implementacin por defecto de diversas interfaces
de soporte del API de Struts 2, entre ellas las relacionadas con la
funcionalidad relativa a la validacin de datos.
Importar el paquete com.opensymphony.xwork2.validator.
annotations. Este proporciona todas las anotaciones asociadas a
cada uno de los validadores predefinidos de Struts 2.

292 STRUTS RA-MA

Una vez realizadas las tareas anteriores, ser necesario incluir la
anotacin @Validation delante de la declaracin de la clase para que Struts 2
reconozca las anotaciones que incluiremos a continuacin para la validacin de los
datos:
package mi scl ases;
i mpor t com. opensymphony. xwor k2. Act i onSuppor t ;
i mpor t com. opensymphony. xwor k2. val i dat or . annot at i ons. *;
@Validation
publ i c cl ass Logi n ext ends Act i onSuppor t {
:
}

Despus, para aplicar una validacin sobre un determinado campo ser
suficiente con indicar la anotacin asociada al validador delante del mtodo getXxx
que devuelve el dato a validar, indicando entre parntesis el mensaje de error que
se quiere mostrar al usuario cuando falle la validacin del dato.
Por ejemplo, para aplicar el validador RequiredStringValidator sobre los
campos username y password, el cual se encarga de comprobar que se ha
introducido al menos un carcter en un campo, habra que definir la clase Login de
la siguiente manera:
package mi scl ases;
i mpor t com. opensymphony. xwor k2. Act i onSuppor t ;
i mpor t com. opensymphony. xwor k2. val i dat or . annot at i ons. *;
@Val i dat i on
publ i c cl ass Logi n ext ends Act i onSuppor t {
pr i vat e St r i ng user name;
pr i vat e St r i ng passwor d;
publ i c St r i ng execut e( ) t hr ows Except i on {
i f ( get Passwor d( ) . equal s( " admi n" ) )
r et ur n SUCCESS; / / const ant e def i ni da
/ / en Act i onSuppor t
el se
r et ur n ERROR; / / const ant e def i ni da
/ / en Act i onSuppor t
}
publ i c voi d set User name( St r i ng us) {
t hi s. user name = us;
}

RA-MA CAPTULO 8. STRUTS 2 293

/ / anot aci n cadena r equer i da
@Requi r edSt r i ngVal i dat or ( message=" debe i nt r oduci r un
usuar i o" )
publ i c St r i ng get User name( ) {
r et ur n t hi s. user name;
}
publ i c voi d set Passwor d( St r i ng pwd) {
t hi s. passwor d = pwd;
}
/ / anot aci n cadena r equer i da
@Requi r edSt r i ngVal i dat or ( message=" debe i nt r oduci r un
passwor d" )
publ i c St r i ng get Passwor d( ) {
r et ur n t hi s. passwor d;
}
}
La utilizacin de anotaciones en el ejemplo anterior para definir las reglas
de validacin, hace que ya no sea necesario crear el archivo Login-validation.xml.
En el caso de que los mensajes se encuentren en un archivo de recursos, en
vez de utilizar el atributo message en la anotacin emplearemos key, mediante el
cual especificaremos la clave asociada al mensaje de error:
@Requi r edSt r i ngVal i dat or ( key=" passwor d. nul o" )
publ i c St r i ng get Passwor d( ) {
r et ur n t hi s. passwor d;
}
Si se incumple alguno de los criterios de validacin definidos en los
diferentes mtodos get a travs de las anotaciones, el usuario ser redirigido a la
pgina de resultado indicada con el nombre input.
Si esta pgina es la misma que contiene los campos de recogida de datos,
no ser necesario utilizar el tag <s:actionerror>para mostrar los mensajes de error,
puesto que las anotaciones de validacin incorporan como funcionalidad implcita
la generacin de los mensajes de error sobre los campos asociados a cada mtodo
get().

294 STRUTS RA-MA

8.6.3.1 TIPOS DE ANOTACIONES DE VALIDACIN
Adems de la anotacin @RequiredStringValidator utilizada como ejemplo
anteriormente, el paquete opensymphony.xwork2.validator.annotations incluye
otras anotaciones con las que poder realizar las validaciones habituales durante la
captura de datos a travs de un formulario. Entre ellas destacamos las siguientes:
@IntRangeFieldValidator. Comprueba que el valor introducido
en un campo est dentro de un determinado rango numrico entero.
A travs de los atributos min y max se define dicho rango.
@DoubleRangeFieldValidator. Comprueba que el valor
introducido en un campo est dentro de un determinado rango
numrico decimal. A travs de los atributos min y max se define
dicho rango.
@StringLengthFieldValidator. Comprueba que la longitud del
texto introducido en el campo se encuentra dentro de un
determinado rango. Los atributos minLength y maxLength definen
la longitud mnima y mxima de la cadena, respectivamente.
@EmailValidator. Comprueba que el valor del campo se ajusta a
un formato de direccin de correo electrnico vlido.
Se pueden definir todas las anotaciones que se consideren necesarias sobre
un determinado mtodo get().
PRCTICA 8.4. LISTADO DE LLAMADAS DE USUARIO
Descripcin
En esta ltima prctica vamos a desarrollar una nueva versin de la
aplicacin del listado de llamadas de usuario que presentamos en la prctica 3.1 del
Captulo 3.
Como recordaremos, la aplicacin consta de una pgina inicial de login
donde se solicitan los credenciales del usuario al que, una vez validado se le da la
opcin de elegir el telfono cuyo listado de llamadas quiere ver. La aplicacin
tambin incluye una pgina de registro para la insercin de nuevos usuarios (figura
44).

RA-MA CAPTULO 8. STRUTS 2 295











Fig. 44. Pginas de la aplicacin
Desarrollo
El desarrollo de esta aplicacin se realizar utilizando Struts 2. La lgica
de negocio ser la misma que en la versin anterior, con tres clases llamadas
GestionClientes, GestionTelefonos y GestionLlamadas, en las que se incluir todo
el cdigo de acceso a datos para la realizacin de las diferentes tareas requeridas
por la aplicacin.
Los beans TarifaBean y LlamadaBean que encapsulan los datos asociados
a cada tipo de tarifa y llamada realizada son iguales tambin a los utilizados en la
versin anterior.
Las tres operaciones a realizar por la operacin, validar usuarios, registrar
usuarios y listar las llamadas, sern controladas por tres clases de tipo Action. La
navegacin a la pgina de registro se realizar a travs de una accin Name.
Por otro lado, la aplicacin realiza la validacin de los datos suministrados
a travs del formulario de registro, para lo cual se incluirn las anotaciones
pertinentes en el Action de registro.

296 STRUTS RA-MA

Listado
Como ya hemos indicado, las clases de negocio y J avaBeans son los
mismos que los desarrollados en la prctica 3.1, por lo que remitimos a dicha
prctica para consultar los listados de cdigo de estas clases.
Los siguientes listados corresponden a las tres clases Action de la
aplicacin:
Validar.java
package act i ons;

i mpor t j ava. ut i l . Ar r ayLi st ;
i mpor t or g. apache. st r ut s2. i nt er cept or . *;
i mpor t or g. apache. st r ut s2. ut i l . *;
i mpor t j avax. ser vl et . ht t p. *;
i mpor t j avax. ser vl et . *;
i mpor t model o. Gest i onCl i ent es;
i mpor t model o. Gest i onTel ef onos;

publ i c cl ass Val i dar i mpl ement s Ser vl et Cont ext Awar e{
pr i vat e St r i ng passwor d=" hol a" ;
pr i vat e St r i ng user name;
pr i vat e Ar r ayLi st <I nt eger > t el ef onos;
Ser vl et Cont ext cont ext ;
publ i c St r i ng execut e( ) t hr ows Except i on {
St r i ng dr i ver =cont ext . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=cont ext . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=
new Gest i onCl i ent es( dr i ver , cadenaCon) ;
i f ( gc. val i dar ( user name, passwor d) ) {
Gest i onTel ef onos gt =
new Gest i onTel ef onos( dr i ver , cadenaCon) ;
t el ef onos=gt . get Tel ef onos( passwor d) ;
r et ur n " ok" ;
}
el se{
r et ur n " er r or " ;
}
}
publ i c St r i ng get Passwor d( ) {
RA-MA CAPTULO 8. STRUTS 2 297

r et ur n passwor d;
}
publ i c voi d set Passwor d( St r i ng passwor d) {
t hi s. passwor d = passwor d;
}
publ i c St r i ng get User name( ) {
r et ur n user name;
}
publ i c voi d set User name( St r i ng user name) {
t hi s. user name = user name;
}
publ i c Ar r ayLi st <I nt eger > get Tel ef onos( ) {
r et ur n t el ef onos;
}
publ i c voi d set Tel ef onos( Ar r ayLi st <I nt eger > t el ef onos) {
t hi s. t el ef onos = t el ef onos;
}
publ i c voi d set Ser vl et Cont ext ( Ser vl et Cont ext cont ext ) {
t hi s. cont ext =cont ext ;
}
}
Registrar.java
package act i ons;

i mpor t or g. apache. st r ut s2. ut i l . *;
i mpor t j avax. ser vl et . *;
i mpor t com. opensymphony. xwor k2. Act i onSuppor t ;
i mpor t com. opensymphony. xwor k2. val i dat or . annot at i ons. *;
i mpor t model o. Gest i onCl i ent es;
@Val i dat i on
publ i c cl ass Regi st r ar ext ends Act i onSuppor t
i mpl ement s Ser vl et Cont ext Awar e{
pr i vat e St r i ng nombr e;
pr i vat e St r i ng apel l i dos;
pr i vat e St r i ng passwor d;
pr i vat e St r i ng usuar i o;
pr i vat e St r i ng emai l ;
Ser vl et Cont ext cont ext ;
publ i c St r i ng execut e( ) t hr ows Except i on {
St r i ng dr i ver =cont ext . get I ni t Par amet er ( " dr i ver " ) ;
298 STRUTS RA-MA

St r i ng cadenaCon=cont ext . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onCl i ent es gc=
new Gest i onCl i ent es( dr i ver , cadenaCon) ;
gc. r egi st r ar ( nombr e,
apel l i dos,
usuar i o,
passwor d,
emai l ) ;
r et ur n " r egi st r ado" ;
}
/ / val i daci n de cadena r equer i da y l ongi t ud
/ / m ni ma par a el passwor d
@Requi r edSt r i ngVal i dat or ( message=" debe i nt r oduci r
un passwor d" )
@St r i ngLengt hFi el dVal i dat or ( mi nLengt h=" 6" ,
message=" el passwor d debe t ener al menos 6 car act er es" )
publ i c St r i ng get Passwor d( ) {
r et ur n passwor d;
}
publ i c voi d set Passwor d( St r i ng passwor d) {
t hi s. passwor d = passwor d;
}
publ i c St r i ng get Apel l i dos( ) {
r et ur n apel l i dos;
}
publ i c voi d set Apel l i dos( St r i ng apel l i dos) {
t hi s. apel l i dos = apel l i dos;
}
/ / val i daci n de cadena r equer i da y val or
/ / vl i do par a el emai l
@Requi r edSt r i ngVal i dat or ( message=" debe i nt r oduci r
un emai l " )
@Emai l Val i dat or ( message=" di r ecci n de emai l no vl i da" )
publ i c St r i ng get Emai l ( ) {
r et ur n emai l ;
}
publ i c voi d set Emai l ( St r i ng emai l ) {
t hi s. emai l = emai l ;
}
publ i c St r i ng get Nombr e( ) {
r et ur n nombr e;
RA-MA CAPTULO 8. STRUTS 2 299

}
publ i c voi d set Nombr e( St r i ng nombr e) {
t hi s. nombr e = nombr e;
}
/ / val i daci n de cadena r equer i da par a
/ / el usuar i o
@Requi r edSt r i ngVal i dat or ( message=" debe
i nt r oduci r un usuar i o" )
publ i c St r i ng get Usuar i o( ) {
r et ur n usuar i o;
}
publ i c voi d set Usuar i o( St r i ng usuar i o) {
t hi s. usuar i o = usuar i o;
}
publ i c voi d set Ser vl et Cont ext ( Ser vl et Cont ext cont ext ) {
t hi s. cont ext =cont ext ;

}
}
Listar.java
package act i ons;

i mpor t j ava. ut i l . Ar r ayLi st ;
i mpor t j avabeans. Ll amadaBean;
i mpor t j avax. ser vl et . Ser vl et Cont ext ;
i mpor t model o. Gest i onLl amadas;
i mpor t or g. apache. st r ut s2. ut i l . Ser vl et Cont ext Awar e;

publ i c cl ass Li st ar i mpl ement s Ser vl et Cont ext Awar e{
pr i vat e i nt t el ef ono;
pr i vat e Ar r ayLi st <Ll amadaBean> l l amadas;
Ser vl et Cont ext cont ext ;
publ i c Ar r ayLi st <Ll amadaBean> get Ll amadas( ) {
r et ur n l l amadas;
}
publ i c voi d set Ll amadas( Ar r ayLi st <Ll amadaBean> l l amadas)
{
t hi s. l l amadas = l l amadas;
}
publ i c i nt get Tel ef ono( ) {
300 STRUTS RA-MA

r et ur n t el ef ono;
}
publ i c voi d set Tel ef ono( i nt t el ef ono) {
t hi s. t el ef ono = t el ef ono;
}
publ i c St r i ng execut e( ) t hr ows Except i on {
St r i ng dr i ver =cont ext . get I ni t Par amet er ( " dr i ver " ) ;
St r i ng cadenaCon=cont ext . get I ni t Par amet er ( " cadenaCon" ) ;
Gest i onLl amadas gl =
new Gest i onLl amadas( dr i ver , cadenaCon) ;
l l amadas=gl . get TodasLl amadasTel ef ono( t el ef ono) ;
r et ur n " l l amadas" ;
}
publ i c voi d set Ser vl et Cont ext ( Ser vl et Cont ext sc) {
t hi s. cont ext =sc;
}
}
Las vistas se han desarrollado utilizando los tags de Struts 2 comentados a
lo largo del Captulo. He aqu los listados de las mismas:
login.jsp
<%@page cont ent Type=" t ext / ht ml " pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD
HTML 4. 01 Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type"
cont ent =" t ext / ht ml ; char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<h1>Hel l o Wor l d! </ h1><br / ><br / ><br / ><br / >
<cent er >
<h1>For mul ar i o de Aut ent i caci n</ h1>
<s: f or mact i on=" l ogi n. act i on" met hod=" post " >
<s: t ext f i el d name=" user name" l abel =" usuar i o" / >
<s: passwor d name=" passwor d" l abel =" passwor d"
showPasswor d=" f al se" / >
RA-MA CAPTULO 8. STRUTS 2 301

<s: submi t val ue=" Ent r ar " / >
</ s: f or m>
</ cent er >
<br / >
<br / >
<a hr ef =" Name. act i on" >Regi st r ese</ a>
</ body>
</ ht ml >
registro.jsp
<%@page cont ent Type=" t ext / ht ml " pageEncodi ng=" UTF- 8" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD
HTML 4. 01 Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type"
cont ent =" t ext / ht ml ; char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<h1>For mul ar i o de r egi st r o</ h1>
<s: f or mact i on=" r egi st r ar . act i on" met hod=" post " >
<s: t ext f i el d name=" nombr e" l abel =" nombr e" / >
<s: t ext f i el d name=" apel l i dos" l abel =" apel l i dos" / >
<s: t ext f i el d name=" usuar i o" l abel =" usuar i o" / >
<s: passwor d name=" passwor d" l abel =" passwor d" / >
<s: t ext f i el d name=" emai l " l abel =" emai l " / >
<s: submi t val ue=" Ent r ar " / >
</ s: f or m>
<br / >
<s: act i oner r or / >
</ body>
</ ht ml >
opciones.jsp
<%@page cont ent Type=" t ext / ht ml " %>
<%@page pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
302 STRUTS RA-MA

<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<t i t l e>Bi enveni da</ t i t l e>
</ head>
<body>
<cent er >
<h1>Li st ado de t el f onos</ h1>
<s: f or mact i on=" l i st ado" >
<s: sel ect name=" t el ef ono" l i st =" t el ef onos"
header Val ue=" - sel ecci one un t el ef ono- "
header Key=" 0" / >

<s: submi t val ue=" Ver l l amadas" / >
</ s: f or m>
</ cent er >
</ body>
</ ht ml >
listado.jsp
<%@page cont ent Type=" t ext / ht ml " pageEncodi ng=" UTF- 8" %>
<%@t agl i b pr ef i x=" s" ur i =" / st r ut s- t ags" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head>
<met a ht t p- equi v=" Cont ent - Type"
cont ent =" t ext / ht ml ; char set =UTF- 8" >
<t i t l e>J SP Page</ t i t l e>
</ head>
<body>
<h1>Ll amadas r eal i zadas</ h1>
<t abl e bor der =" 1" >
<t r >
<t h>Dest i no</ t h>
<t h>Dur aci n</ t h>
<t h>Fecha</ t h>
</ t r >
<s: i t er at or val ue=" l l amadas" >
RA-MA CAPTULO 8. STRUTS 2 303

<t r >
<t d><s: pr oper t y val ue=" dest i no" / ></ t d>
<t d><s: pr oper t y val ue=" dur aci on" / ></ t d>
<t d><s: pr oper t y val ue=" f echa" / ></ t d>
</ t r >
</ s: i t er at or >
</ t abl e>
</ body>
</ ht ml >
En cuanto a los archivos de configuracin, quedarn como se indica en los
siguientes listados.
struts.xml
<! DOCTYPE st r ut s PUBLI C
" - / / Apache Sof t war e Foundat i on/ / DTD St r ut s Conf i gur at i on
2. 0/ / EN"
" ht t p: / / st r ut s. apache. or g/ dt ds/ st r ut s- 2. 0. dt d" >

<st r ut s>
<const ant name=" st r ut s. enabl e. Dynami cMet hodI nvocat i on"
val ue=" f al se" / >
<const ant name=" st r ut s. devMode" val ue=" f al se" / >
<package name=" val i daci on" namespace=" / "
ext ends=" st r ut s- def aul t " >
<act i on name=" l ogi n" cl ass=" act i ons. Val i dar " >
<r esul t name=" ok" >/ opci ones. j sp</ r esul t >
<r esul t name=" er r or " >/ l ogi n. j sp</ r esul t >
</ act i on>
<act i on name=" r egi st r ar " cl ass=" act i ons. Regi st r ar " >
<r esul t name=" r egi st r ado" >/ l ogi n. j sp</ r esul t >
<r esul t name=" i nput " >/ r egi st r o. j sp</ r esul t >
</ act i on>
<act i on name=" l i st ado" cl ass=" act i ons. Li st ar " >
<r esul t name=" l l amadas" >/ l i st ado. j sp</ r esul t >
</ act i on>
<act i on name=" Name" >
<r esul t >/ r egi st r o. j sp</ r esul t >
</ act i on>
</ package>
</ st r ut s>
304 STRUTS RA-MA

web.xml
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<web- app ver si on=" 2. 5"
xml ns=" ht t p: / / j ava. sun. com/ xml / ns/ j avaee"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSchema- i nst ance"
xsi : schemaLocat i on=" ht t p: / / j ava. sun. com/ xml / ns/ j avaee
ht t p: / / j ava. sun. com/ xml / ns/ j avaee/ web- app_2_5. xsd" >
<cont ext - par am>
<par am- name>dr i ver </ par am- name>
<par am- val ue>com. mysql . j dbc. Dr i ver </ par am- val ue>
</ cont ext - par am>
<cont ext - par am>
<par am- name>cadenaCon</ par am- name>
<par am- val ue>
j dbc: mysql : / / l ocal host : 3306/ t el ef oni a
</ par am- val ue>
</ cont ext - par am>
<f i l t er >
<f i l t er - name>st r ut s2</ f i l t er - name>
<f i l t er - cl ass>
or g. apache. st r ut s2. di spat cher . Fi l t er Di spat cher
</ f i l t er - cl ass>
</ f i l t er >
<f i l t er - mappi ng>
<f i l t er - name>st r ut s2</ f i l t er - name>
<ur l - pat t er n>/ *</ ur l - pat t er n>
</ f i l t er - mappi ng>
<wel come- f i l e- l i st >
<wel come- f i l e>l ogi n. j sp</ wel come- f i l e>
</ wel come- f i l e- l i st >
</ web- app>



9Apndice A
EL LENGUAJE DE EXPRESIONES DE JSP
El lenguaje de expresiones de J SP, ms conocido como EL, es un lenguaje
de programacin basado en la utilizacin de expresiones dentro de una pgina JSP
para la generacin de resultados en el interior de la misma. Este lenguaje se
incorpor a la especificacin J SP a partir de la versin 2.0, la cual forma parte del
conjunto de tecnologas J avaEE 1.4.
El objetivo de este lenguaje es reemplazar a las clsicas expresiones J SP
basadas en la utilizacin de cdigo J ava, contribuyendo as a la reduccin e incluso
eliminacin en algunos casos de la utilizacin de scriptlets J ava dentro de una
pgina J SP.
Mediante la utilizacin de sencillas instrucciones el lenguaje EL posibilita
el acceso a los parmetros enviados en una peticin, a las cookies o a los datos
almacenados en cualquiera de los mbitos de la aplicacin.
Como otros lenguajes de programacin, EL soporta la utilizacin de
operadores y palabras reservadas.
Por sus caractersticas, el lenguaje EL constituye un excelente
complemento de las acciones J SP de Struts para la creacin de vistas,
contribuyendo an ms a reducir la complejidad de las pginas J SP en las
aplicaciones MVC.

306 STRUTS RA-MA

EXPRESIONES EL
Las expresiones EL devuelven un valor al lugar de la pgina donde est
situada la expresin. Su sintaxis es:
${expresion}
donde expresion es cualquier expresin sintctica vlida EL que devuelva un
resultado. Estas expresiones pueden incluir referencias a variables J SP, objetos
implcitos EL, datos almacenados en cualquiera de los mbitos de aplicacin o
incluso alguna operacin entre datos utilizando alguno de los operadores
soportados por EL.
Por ejemplo, siendo midato el nombre de alguna variable J SP, la
siguiente instruccin mostrara en la pgina el valor de dicha variable:
El val or de l a var i abl e es ${mi dat o}
Lo anterior es equivalente a:
El val or de l a var i abl e es <%=mi dat o%>
pero con la ventaja en el caso de EL de no tener que utilizar scriptlets J ava.
Es importante destacar que una expresin EL no puede acceder a
variables u objetos creados en scriptlets Java. Por ejemplo, el siguiente bloque
de sentencias no generara ningn resultado en la pgina puesto que la variable
dato no existira para EL:
<%i nt dat o=10; %>
r esul t ado: ${dat o}
Las expresiones EL pueden utilizarse bien para generar un texto dentro de
la pgina de respuesta o bien para establecer el valor de un atributo de alguna
accin J SP (incluidos los tags de Struts) que acepte expresiones. El siguiente
ejemplo utiliza una expresin EL para obtener el valor a asignar a la variable
parametro:
<bean: def i ne i d=" par amet r o" val ue=" ${par am[ ' par ' ] }" / >


RA-MA APNDICE A. EL LENGUAJ E DE EXPRESIONES DE J SP 307

ACCESO A VARIABLES DE MBITO
La recuperacin de un dato almacenado en alguno de los mbitos de la
aplicacin resulta tan simple con EL como indicar el nombre del dato entre los
smbolos ${ y }. Si el objeto es de tipo J avaBean el acceso a las propiedades
de mismo se llevar a cabo utilizando la sintaxis:
objeto.propiedad
Por ejemplo, si tenemos un objeto de identificador ValidacionForm con
dos propiedades, usuario y password, almacenado en un mbito de sesin y
desde una pgina J SP cualquiera de la aplicacin quisiramos obtener el valor de
sus propiedades deberamos utilizar las expresiones:
${ValidacionForm.usuario}
y
${ValidacionForm.password}
El siguiente bloque de instrucciones de ejemplo hara que se mostrase el
texto Mensaje de prueba en la pgina de respuesta:
<j sp: useBean i d=" i nf o" cl ass=" j avabeans. Dat os" >
<j sp: set Pr oper t y name=" i nf o"
pr oper t y=" cl ave" val ue=" Mensaj e de pr ueba" / >
</ j sp: useBean>
Mensaj e: <h3>${i nf o. cl ave}</ h3>
Si el objeto es de tipo coleccin el acceso a sus elementos se realizar, en
el caso de colecciones basadas en ndices:
${objeto_coleccion[indice]}
mientras que para colecciones basadas en claves ser:
${objeto_coleccion[nombre_clave]}
En este ltimo caso tambin es posible utilizar la siguiente expresin para
acceder al valor del elemento de la coleccin:
${objeto_coleccion.nombre_clave}
308 STRUTS RA-MA

Por ejemplo, si tenemos una coleccin de tipo Map llamada basedatos en
la que se almacenan los nombres de personas asocindoles como clave el DNI, la
siguiente instruccin mostrar el nombre de la persona cuyo DNI sea 30005W:
Su nombr e es <b>${basedat os[ " 30005W" ] }</ b>
O tambin:
Su nombr e es <b>${basedat os. 30005W}</ b>
OBJETOS IMPLCITOS EL
El lenguaje EL incluye una serie de objetos implcitos que permiten
acceder de una forma sencilla a toda la informacin que los distintos objetos del
API servlet proporcionan a la aplicacin, como son las variables de pgina,
peticin, sesin o aplicacin, los parmetros y encabezados de la peticin, las
cookies y los parmetros de contexto de inicializacin.
Estos objetos son expuestos como colecciones de tipo Map, accedindose a
las propiedades y variables proporcionadas por stos mediante la expresin:
${objeto_implicito[clave]}
siendo clave el nombre de la propiedad o variable cuyo valor se quiere obtener.
Al igual que con cualquier otro tipo de coleccin, tambin podramos
utilizar la siguiente expresin para acceder al valor del dato:
${objeto_implicito.clave}
Los objetos implcitos que forman parte del lenguaje EL son:
pageScope. Proporciona acceso a las variables de mbito de
pgina.
requestScope. Proporciona acceso a las variables de mbito de
peticin. Por ejemplo, dado el siguiente bloque de sentencias
incluidas en una pgina J SP:
<%i nt codi go=Mat h. cei l ( Mat h. r andom( ) *500) ;
r equest . set At t r i but e( " codi go" , codi go) ; %>
<j sp: f or war d page=" pr ueba. j sp" / >
RA-MA APNDICE A. EL LENGUAJ E DE EXPRESIONES DE J SP 309

Si quisiramos mostrar en la pgina prueba.jsp el valor de la
variable de peticin codigo, utilizaramos:
El cdi go gener ado es: ${r equest Scope[ " codi go" ] }
sessionScope. Proporciona acceso a las variables de mbito de
sesin. Por ejemplo, supongamos que en una pgina J SP tenemos
el siguiente bloque de instrucciones:
<j sp: useBean i d=" obj " cl ass=" j avabeans. Dat os"
scope=" sessi on" / >
<j sp: set Pr oper t y name=" obj "
pr oper t y=" numer o" val ue=" 35" / >
<%r esponse. sendRedi r ect ( " pr ueba. j sp?par =35" ) ; %>
Por otro lado, en la pgina prueba.jsp queremos comparar el valor
del atributo par con la propiedad numero del J avaBean de
sesin, mostrando un mensaje en el caso de que sean iguales. Este
ser el bloque de cdigo que tendremos que incluir en la pgina
suponiendo que estamos utilizando Struts:
<l ogi c: equal par amet er =" par "
val ue=" ${sessionScope['obj'].numero}" >
<h1>La condi ci n se cumpl e! </ h1>
</ l ogi c: equal >
applicationScope. Proporciona acceso a las variables de mbito de
aplicacin.
param. Mediante este objeto tenemos acceso a los parmetros
enviados en la peticin. Por ejemplo, el siguiente bloque de
sentencias inicializara la propiedad nombre del J avaBean
usuario con el valor del parmetro user recibido en la peticin:
<j sp: useBean i d=" usuar i o" cl ass=" j avabeans. Usuar i o" / >
<j sp: set Pr oper t y name=" usuar i o" pr oper t y=" nombr e"
val ue=" ${par am[ ' user ' ] }" / >
paramValues. Al igual que el anterior proporciona acceso a los
parmetros de peticin, slo que en este caso el valor de cada
parmetro se recupera como un array de cadenas. Se utiliza en los
casos en que el parmetro incluye mltiples valores.
310 STRUTS RA-MA

header. Proporciona acceso a los encabezados de la peticin. El
siguiente ejemplo mostrara en la pgina el valor del encabezado
user-agent enviado en la peticin actual:
Ti po navegador : ${header [ ' user - agent ' ] }
headerValues. Al igual que header proporciona acceso a los
encabezados de la peticin, devolviendo en este caso un array de
cadenas con todos los valores que le han sido asignados al
encabezado.
cookie. Proporciona acceso a las cookies enviadas en la peticin.
Cada elemento de la coleccin Map asociada representa un objeto
cookie. La siguiente expresin de ejemplo mostrara en la pgina el
contenido de la cookie user:
Usuar i o: ${cooki e[ " user " ] }
Adems de los anteriores objetos Map, el lenguaje EL proporciona otro
objeto implcito llamado pageContext que proporciona acceso al contexto de la
aplicacin. Entre otras dispone de una serie de propiedades que nos dan acceso a
los objetos implcitos J SP, por ejemplo, la siguiente expresin EL permitira
recuperar el mtodo de envo utilizado en la peticin actual:
${pageCont ext . r equest . met hod}
OPERADORES EL
El lenguaje EL tambin incluye una serie de operadores que permiten
manipular datos dentro de una expresin. La tabla de la figura 45 contiene los
principales operadores EL agrupados por categoras. Para algunos de ellos se indica
entre parntesis otro smbolo o nombre alternativo a utilizar.



Fig. 45. Tabla de operadores EL
Categora Operadores
Aritmticos +, -, *, / (div), % (mod)
Relacionales ==(eq), !=(ne), <(lt), >(gt), <=(le) y >=(ge)
Lgicos &&(and), ||(or) y !(not)
RA-MA APNDICE A. EL LENGUAJ E DE EXPRESIONES DE J SP 311

Por otro lado, la tabla indicada en la figura 46 incluye algunos ejemplos de
expresiones EL que utilizan algunos de los operadores anteriores, indicando el
resultado generado en cada caso.




Fig. 46. Ejemplos de expresiones EL con operadores
Adems de estos operadores clsicos, EL incluye otros dos operadores
especiales:
empty. Comprueba si una coleccin o cadena es vaca o nula,
devolviendo el valor true en caso afirmativo y false si no lo es. Por
ejemplo, la siguiente expresin devolvera true si no se ha recibido
ningn valor en el parmetro password:
${empt y par am[ " passwor d" ] }
Operador condicional. El operador condicional ? : funciona de
forma muy similar al operador J ava del mismo tipo, siendo su
sintaxis de utilizacin:
${condicion? expresionA:expresionB}
Si la condicin da como resultado el valor true se evaluar
expresionA, mientras que si el resultado es false se ejecutar
expresionB.
El siguiente ejemplo devolver el valor de la variable de sesin
contador en caso de que no exista la cookie user, generando el
valor 0 en caso contrario:
${empt y cooki e[ " user " ] ?sessi onScope[ " cont ador " ] : 0}


Expresin ejemplo Resultado
${4+5*7} 39
${4 mod 3} 1
${10>7 $$ 5!=3} true
${5 gt 2 || 7 le 6} true


10Apndice B
LA LIBRERA DE ACCIONES ESTNDAR
DE JSP (JSTL)
La librera de acciones J STL consta de un conjunto de tags J SP que
permiten realizar tareas habituales de procesamiento en una pgina J SP sin
necesidad de recurrir a scriptlets J ava.
La mayor parte de la funcionalidad proporcionada por las acciones logic y
bean de Struts puede ser conseguida con las acciones estndares J STL, resultando
incluso ms sencilla la utilizacin de estos tags que los de Struts. Por ello es comn
combinar ambos tipos de etiquetas en la construccin de vistas para las
aplicaciones Struts.
Las acciones J STL estn pensadas para utilizar el lenguaje EL en la
definicin de los valores de sus atributos:
<c:set var="info" value="${dato}"/>
Durante este ltimo apndice estudiaremos las acciones ms importantes
de esta librera y los pasos a seguir para su utilizacin.
INSTALACIN DE JSTL
Aunque es soportada desde la versin J SP 1.2, no ha sido hasta la versin
J avaEE 5.0 (J SP 2.1) cuando J STL se ha integrado en la plataforma J avaEE. No
obstante, podemos descargarla de forma independiente desde la direccin:
314 STRUTS RA-MA

http://java.sun.com/products/jsp/jstl/
Dos son los archivos que proporcionan todo el soporte para la utilizacin
de J STL: jstl.jar y standard.jar, ambos debern ser incluidos en el directorio
WEB-INF\lib de la aplicacin.
Probablemente, si estamos utilizando algn entorno de desarrollo con
soporte para J avaEE 5, como Eclipse o NetBeans, los componentes de la librera se
incluyan en otros archivos .jar diferentes a stos y sean incorporados de forma
automtica al proyecto por el asistente de creacin del mismo.
UTILIZACIN DE ACCIONES JSTL
Una vez desplegados los archivos .jar en el directorio de libreras podemos
hacer uso de las acciones J STL desde cualquiera de las pginas J SP de la
aplicacin.
El conjunto de acciones J STL est compuesto realmente por cinco
libreras, de las cuales es la librera core la que proporciona el grupo de acciones de
uso general, que son en definitiva las de ms amplia utilizacin y sobre las que nos
centraremos en este estudio.
Para poder utilizar las acciones core en una pgina J SP es necesario incluir
la siguiente directiva taglib en la pgina:
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Como vemos, suele ser convenio utilizar el prefijo c para referirse a las
acciones del core.
ANLISIS DE LAS PRINCIPALES ACCIONES JSTL
A lo largo de esta seccin vamos a analizar las principales acciones J STL
que componen la librera core. Para facilitar nuestro estudio vamos a dividir este
conjunto de acciones en dos grupos, segn la funcionalidad proporcionada por las
mismas:
Acciones genricas.
Acciones de control de flujo.
RA-MA APNDICE B. LA LIBRERA DE ACCIONES ESTNDAR DE J SP (J STL) 315

Acciones genricas
Incluye acciones de uso general en la realizacin de tareas habituales en
una pgina J SP, como la insercin de datos en la pgina de respuesta, manipulacin
de variables, etc.
Veamos a continuacin las acciones ms importantes de este grupo.
OUT
Realiza la misma funcin que una scriplet J SP del tipo:
<%=expresion%>
Tambin es equivalente a la accin Struts <bean:write/>, es decir, inserta
un determinado valor en la pgina de respuesta. Su principal atributo, value,
contiene la expresin EL que determina el valor a incluir en la pgina. El siguiente
ejemplo mostrara una frase con el valor del parmetro email enviado en la
peticin:
La di r ecci n de cor r eo el ect r ni co es:
<c: out val ue=" ${par am[ ' emai l ' ] }" / >
Se puede indicar mediante el atributo default un valor por defecto para
mostrar en la pgina en caso de que no se localice el dato indicado en value:
La di r ecci n de cor r eo el ect r ni co es:
<c: out val ue=" ${par am[ ' emai l ' ] }"
def aul t =" def aul t @di r ecci on. com" / >
SET
Se emplea para establecer un valor en una variable J SP, en una propiedad
de un J avaBean o en una coleccin de tipo Map. Sus atributos son:
var. Identificador de la variable J SP a la que se asignar el valor.
target. En caso de tratarse de una asignacin a un objeto
(J avaBean o coleccin), esta propiedad indicar el identificador
asociado a dicho objeto.
property. Propiedad del objeto J avaBean a la que se le asignar el
valor. Si target especifica una coleccin Map en vez de un objeto
316 STRUTS RA-MA

J avaBean, property contendr la clave asociada al dato que se va a
aadir a la coleccin.
scope. mbito de contexto en el que se definir la variable. Sus
posibles valores son: page, request, session y application.
value. Valor que se asignar a la variable, propiedad de J avaBean
o coleccin, segn cules de los atributos anteriores se hayan
especificado.
La siguiente instruccin asigna el valor 40 a la variable res:
<c: set var =" r es" val ue=" ${5*8}" / >
En este otro ejemplo se asigna el valor del parmetro telefono a la
propiedad contacto del J avaBean persona:
<c: set t ar get =" per sona"
pr oper t y=" cont act o" val ue=" ${par am[ ' t el ef ono' ] }" / >
Finalmente, en este otro ejemplo se asigna una cadena de caracteres
existente en el atributo de sesin user en el elemento de la coleccin usuarios
que tiene como clave asociada 5555J :
<c: set t ar get =" usuar i os" pr oper t y=" 5555J "
val ue=" ${sessi onScope[ ' user ' ] }" / >
REMOVE
Elimina una variable existente en uno de los mbitos de la aplicacin. Sus
atributos son:
var. Identificador de la variable a eliminar.
scope. mbito donde se encuentra la variable. Si no se especifica
se buscar en todos los mbitos de la aplicacin.
CATCH
Permite capturar una excepcin dentro de la pgina J SP. El formato de
utilizacin de la accin es el siguiente:

RA-MA APNDICE B. LA LIBRERA DE ACCIONES ESTNDAR DE J SP (J STL) 317


<c:catch var="variable">
acciones posible excepcin
</c:catch>
Si se produce alguna excepcin en el cuerpo de la accin <c:catch>se
almacenar el objeto Exception generado en la variable cuyo nombre se indica en
el atributo var del tag, interrumpindose la ejecucin del bloque y pasando el
control del programa a la primera sentencia despus del catch.
REDIRECT
Realiza la misma funcin que el mtodo sendRedirect() del objeto
HttpServletResponse, redireccionando al usuario hacia un nuevo recurso cuya
direccin estar especificada en el atributo url de la accin.
Opcionalmente se pueden enviar parmetros al destinatario, para lo cual
habr que utilizar la accin <c:param>en el interior de <c:redirect>. El bloque de
acciones del siguiente ejemplo redireccionara al usuario al servlet entrar,
pasndole en la peticin los parmetros codigo y localizacion:
<c: r edi r ect ur l =" ent r ar " >
<c: par amname=" codi go" val ue=" 97811" / >
<c: par amname=" l ocal i zaci on" val ue=" J AZ10" / >
</ c: r edi r ect >
Control de flujo
Las acciones incluidas en este grupo permiten controlar el flujo de
ejecucin dentro de las pginas J SP.
Seguidamente presentaremos las acciones ms importantes de este grupo.
IF
Evala el cuerpo de la accin si el resultado de la condicin indicada en su
atributo test es true. El cdigo del siguiente ejemplo mostrara en la pgina de
respuesta el valor de la variable num en caso de que ste sea un nmero par:
<c: i f t est =" ${num%2 == 0}" >
El nmer o es <c: out val ue=" ${num}" / >
318 STRUTS RA-MA

</ c: i f >
CHOOSE
Su formato es similar al de la accin <c:if>, slo que en este caso se
comprueban varias condiciones, evalundose el cuerpo de la primera que resulte
verdadera. La estructura de <c:choose>es:
<c:choose>
<c:when test="condicion1">
cuerpo1
</c:when>
<c:when test="condicion2">
cuerpo2
</c:when>
:

<c:otherwise>
otros
</c:otherwise>
</c:choose>
El siguiente ejemplo muestra distintos mensajes en la pgina de respuesta
en funcin del valor de la variable hora:
<c: choose>
<c: when t est =" ${hor a>8 && hor a<13}" >
Buenos d as
</ c: when>
<c: when t est =" ${hor a>13 && hor a<20}" >
Buenas t ar des
</ c: when>
<c: ot her wi se>
Buenas noches
</ c: ot her wi se>
</ c: choose>
RA-MA APNDICE B. LA LIBRERA DE ACCIONES ESTNDAR DE J SP (J STL) 319

FOREACH
Procesa de forma repetitiva el cuerpo de la accin. Se puede utilizar de dos
formas posibles:
1. Recorrido de un rango de valores numrico. En este caso la
variable especificada en su atributo var es inicializada al valor
numrico indicado en el atributo begin, evalundose el cuerpo de
la accin hasta que la variable alcance el valor indicado en el
atributo end. El valor de incremento de la variable al final de cada
iteracin deber ser especificado mediante el atributo step.
El siguiente bloque de acciones mostrara en la pgina de respuesta
la tabla de multiplicar del nmero 7:
<t abl e bor der =" 1" >
<c: f or each var =" i " begi n=" 1" end=" 10" st ep=" 1" >
<t r ><t d><c: out val ue=" ${7*i }" / ></ t d></ t r >
</ c: f or each>
</ t abl e>
2. Recorrido de una coleccin. En este caso la variable indicada en
var recorrer la coleccin especificada en el atributo items,
apuntado con la variable indicada en var a cada elemento de la
coleccin. El cuerpo de la accin ser evaluado con cada iteracin.
El siguiente ejemplo mostrar en la pgina el contenido de la
coleccin nombres:
<c: f or Each var =" nombr e" i t ems=" ${nombr es}" >
<c: out val ue=" ${nombr e}" / >
</ c: f or Each>
FORTOKENS
Esta accin se utiliza para recorrer una lista de objetos String o tokens,
integrados en una cadena de caracteres. Dispone de los siguientes atributos:
items. Cadena de caracteres cuyo contenido se va a recorrer.
var. Variable que apuntar en cada iteracin a uno de los token de
la cadena.
delims. Carcter utilizado como separador de token.
320 STRUTS RA-MA

En la siguiente pgina J SP de ejemplo se recorre una cadena de caracteres
formada por una lista con los nombres de los das de la semana y muestra su
contenido en una tabla XHTML dentro de la pgina de respuesta:
<%@t agl i b ur i =" ht t p: / / j ava. sun. com/ j st l / cor e" pr ef i x=" c" %>
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01
Tr ansi t i onal / / EN"
" ht t p: / / www. w3. or g/ TR/ ht ml 4/ l oose. dt d" >
<ht ml >
<head></ head>
<body>
<c: set var =" di as" val ue=" l unes, mar t es,
mi r col es, j ueves, vi er nes, sbado, domi ngo" / >
<t abl e bor der =" 1" >
<c: f or Tokens var =" di a" i t ems=" ${di as}" del i ms=" , " >
<t r >
<t d>
<c: out val ue=" ${di a}" / >
</ t d>
</ t r >
</ c: f or Tokens >
</ t abl e>
</ body>
</ ht ml >



NDICE ALFABTICO
@
@ actionerror ............................... 293
@DoubleRangeFieldValidator .... 294
@EmailValidator ......................... 294
@IntRangeFieldValidator ........... 294
@RequiredStringValidator .......... 292
@StringLengthFieldValidator ..... 294
@validation ................................. 292
A
acciones J STL .............................. 313
action ............................. 64, 134, 243
Action .................................... 40, 226
action, atributo ....................... 70, 273
Action, objetos Struts 2 ............... 226
ActionContext ............................. 259
actionerror ................................... 290
actionerror, accin ....................... 286
ActionErrors ................ 127, 128, 135
ActionForm ..... 40, 43, 125, 127, 171
ActionForward ................... 41, 44, 74
ActionInvocation ......................... 260
ActionMapping .............................. 40
ActionMessage ............ 128, 129, 135
ActionMessages ........................... 196
actions, paquete ............................. 91
ActionServlet ..................... 39, 43, 87
add, mtodo ................................. 128
addActionError, mtodo ............. 286
AJ AX .......................................... 238
anotaciones .................................. 238
anotaciones, validacin ............... 291
ApplicationAware ....................... 249
ApplicationResource.properties . 176,
187
ApplicationResources.properties ... 38
applicationScope ......................... 309
B
bean
cookie ...................................... 145
define ....................................... 147
header ...................................... 146
message ................................... 146
page ......................................... 149
parameter ................................. 145
size........................................... 149
write......................................... 144
Bean .............................................. 42
bean, accin ................................. 269
bean, librera ............................... 143
322 STRUTS RA-MA

bean:write ...................................... 72
byte, validador ............................. 185
C
checkbox, accin ......................... 279
choose, accin.............................. 318
cols, atributo ................................ 275
Controlador .................................... 21
controller ....................................... 89
cookie .......................................... 310
D
defaultStack ................................. 248
definicin ..................................... 209
definition ............................. 210, 211
definition, atributo ....................... 212
destroy, mtodo ........................... 258
DispatchAction .............................. 92
double, validador ......................... 185
doubleRange, validador ............... 186
E
EL, expresiones ........................... 306
EL, lenguaje de expresiones ........ 305
EL, objetos implcitos .................. 308
EL, operadores ............................. 310
EL, variables ................................ 307
else, accin .................................. 271
email, validador ........................... 187
empty, operador EL ..................... 311
excepciones ................................. 133
exception ..................................... 134
ExceptionHandler ........................ 139
execute, mtodo .... 40, 41, 44, 50, 59,
62, 89, 92, 93, 106, 126, 139, 226,
242, 249, 258
F
field .............................. 175, 183, 289
Field ............................................. 196
field-validator .............................. 289
fieldValue, atributo ...................... 279
FileUploadInterceptor ................. 246
FilterDispatcher ................... 224, 241
findForward(), mtodo .................. 60
float, validador ............................ 185
foreach, accin ............................ 319
form ............................................. 175
form, accin ................................. 273
form-bean ...................................... 55
form-beans ..................................... 55
formset......................................... 178
form-validation ............................ 178
forward .......................................... 64
forward, atributo ........................... 69
FrontControler ............................... 39
G
get, mtodo .................................. 259
getAction, mtodo ....................... 259
getApplication, mtodo ............... 260
getInputForward(), mtodo ........... 60
getInvocationContext, mtodo .... 259
getKeyMethodMap, mtodo ........ 106
getParameters, mtodo ................ 260
getPathInfo, mtodo ...................... 24
getSession, mtodo ...................... 260
getValueAsString, mtodo ........... 197
global-exception .......................... 134
global-forward ............................... 64
H
handler, atributo .................. 135, 139
header .......................................... 310
headerKey, atributo ..................... 279
headerValue, atributo .................. 279
headerValues ............................... 310
href, atributo .......................... 70, 245
HTML ........................................... 41
html:chceckbox ............................. 69
html:errors ................................... 127
RA-MA NDICE ALFABTICO 323

html:form ....................................... 67
html:html ....................................... 66
html:link ........................................ 69
html:option .................................... 68
html:password ............................... 68
html:radio ...................................... 69
html:select ..................................... 68
html:submit .................................... 68
html:text ......................................... 67
html:textarea .................................. 68
HttpServletRequest ...................... 196
I
if, accin .............................. 271, 317
include ......................................... 237
init, mtodo .................................. 258
init-param ...................................... 52
input, atributo ................................ 63
integer, validador ......................... 185
intercept, mtodo ................. 258, 260
interceptor .................................... 246
Interceptor, interfaz ..................... 258
interceptores ........................ 225, 245
interceptores personalizados ........ 258
interceptor-ref .............................. 247
interceptor-stack .......................... 247
intRange, validador ..................... 185
invoke, mtodo ............................ 260
iterator, accin ............................. 271
J
J 2EE ................................... 21, 23, 37
J avaBean ........................................ 24
J STL, acciones de control
de flujo .................................. 317
J STL, acciones genricas ............. 315
J STL, instalacin ......................... 313
J STL, librera de acciones ........... 313
J STL, utilizacin.......................... 314
K
key, atributo ................................. 135
L
label, atributo .............................. 274
lenguaje de expresiones ............... 305
linkName, atributo ......................... 70
list, atributo ................................. 279
listKey, atributo ........................... 278
listValue, atributo ........................ 278
logic
equal ........................................ 151
forward .................................... 155
greaterEqual ............................ 154
greaterThan ............................. 154
iterate ....................................... 157
lessEqual ................................. 154
lessThan ................................... 154
match ....................................... 154
noMatch ................................... 155
notEqual .................................. 154
redirect ..................................... 155
Logic ............................................. 42
logic, librera ............................... 150
long, validador ............................. 185
LookupDispatchAction ............... 106
M
MappingDispatchAction ............. 113
mask, validador ........................... 187
maxlength, atributo ........................ 67
maxlength, validador ................... 184
message ....................................... 290
method, atributo ..................... 67, 273
minlength, validador ................... 183
Modelo .......................................... 22
Modelo Vista Controlador . 20, 22, 35
msg .............................................. 188
msg, atributo ........................ 174, 200
MVC ............................................ 223
324 STRUTS RA-MA

N
name, atributo .......... 63, 64, 273, 279
namespace, atributo ..................... 273
Nested ............................................ 42
O
operador condicional EL ............. 311
operadores EL .............................. 310
out, accin ................................... 315
P
package ........................................ 228
page, atributo ............................... 207
pageScope .................................... 308
pgina J SP ..................................... 22
param ........................................... 309
param, accin ............................... 269
parameter, atributo ...................... 114
parameter, mtodo ........................ 94
ParameterAware .......................... 249
paramValues ................................ 309
password, accin.......................... 275
path, atributo ......................... 63, 135
plantillas ................................ 39, 201
POJ O ........................... 226, 237, 248
PrincipalAware ............................ 249
processActionCreate, mtodo ........ 89
processActionForm, mtodo .......... 88
processActionPerform, mtodo ..... 89
processForwardConfig, mtodo .... 89
processMapping, mtodo .............. 88
processorClass, atributo ................ 90
processPath, mtodo ..................... 88
processPopulate, mtodo .............. 88
processPreprocess, mtodo ........... 88
processValidate, mtodo ....... 88, 126
property ....................................... 245
property, accin ........................... 269
property, atributo ................... 67, 128
push, accin ................................. 270
put ................................................ 211
R
radio, accin ................................ 277
readonly, atributo .................. 68, 274
redirect, accin ............................ 317
remove, accin ............................ 316
RequestAware ............................. 249
RequestProcessor .......... 87, 126, 202
requestScope ............................... 308
requiredstring .............................. 290
reset, mtodo ......................... 55, 126
result .................................... 243, 290
rows, atributo ............................... 275
S
scope, atributo ............................... 63
select, accin ............................... 279
sendRedirect, mtodo .................. 317
servlet ............................................ 21
servlet-class ................................... 52
ServletConfigInterceptor ..... 249, 250
ServletContextAware .................. 249
ServletRequestAware .................. 249
ServletResponseAware ............... 249
SessionAware .............................. 249
sessionScope ............................... 309
set, accin ............................ 270, 315
setServletRequest, mtodo ........... 250
short, validador ............................ 185
showPassword, atributo .............. 275
Struts ....................................... 36, 37
Struts 2 ........................................ 223
Struts 2, archivo de
configuracin ........................... 227
Struts 2, clases de accin ............. 226
Struts 2, componentes ................. 224
Struts 2, estructura de
aplicaciones ............................. 240
Struts 2, interceptores .......... 225, 245
Struts 2, librera de acciones ....... 267
Struts 2, libreras de acciones ...... 227
Struts 2, requerimientos .............. 239
RA-MA NDICE ALFABTICO 325

Struts 2, validadores .................... 286
Struts, API ..................................... 39
Struts, archivo de configuracin .... 37
Struts, componentes ....................... 37
Struts, control de excepciones ..... 139
Struts, estructura de aplicaciones... 51
Struts, instalacin .......................... 45
Struts, librera de acciones ........... 143
Struts, libreras ............................... 41
Struts, tiles ................................... 201
Struts, validadores ....................... 171
struts.xml ............................. 226, 227
struts-config.xml ...................... 37, 39
struts-default.xml ......................... 229
StrutsStatics ................................. 259
submit, accin .............................. 275
T
taglib, directiva ..... 65, 144, 150, 203,
267, 314
textarea, accin ............................ 275
textfield, accin ........................... 273
tiles .............................................. 201
Tiles ............................................... 42
tiles, librera ................................. 203
tiles:getAsString .......................... 204
tiles:insert .................... 203, 207, 212
tiles:put ........................................ 208
tiles-definitions ............................ 210
tiles-defs.xml ......................... 39, 210
try-catch ....................................... 133
type, atributo .................. 63, 135, 289
U
uri, atributo .................................... 65
url-pattern ...................................... 52
V
validadores .......................... 171, 183
validadores predefinidos ............. 193
validadores Struts 2 ..................... 286
validate, atributo ................... 63, 290
validate, mtodo ... 55, 126, 171, 175,
193
validation.xml ................ 39, 172, 286
validator....................................... 198
Validator ...................................... 196
ValidatorAction ........................... 196
ValidatorForm ............. 175, 178, 193
validator-rules.xml ................ 39, 172
value, atributo .............................. 274
var ................................................ 183
var-value ...................................... 184
Vista .............................................. 22
W
WebWork .................................... 223
X
XHTML......................................... 22





TEXTO CONTRAPORTADA
Ttulo del libro

La creciente demanda de nuevas funcionalidades y servicios requeridos a
las aplicaciones Web modernas se est traduciendo en un aumento de la
complejidad de los desarrollos, haciendo indispensable en la mayora de los casos
el empleo de algn tipo de utilidad que facilite la tarea del programador.
En este contexto se enmarca Struts, sin lugar a dudas el marco de trabajo
ms popular para la construccin de aplicaciones Web con tecnologas J avaEE. Su
metodologa de desarrollo y el amplio conjunto de utilidades y componentes que
proporciona permite crear en un corto espacio de tiempo complejas aplicaciones
Web totalmente robustas y escalables, lo que se ha traducido en el hecho de que
Struts sea el framework preferido por la comunidad de desarrolladores J avaEE para
la construccin de sus aplicaciones.
En este libro se analiza tanto la metodologa de trabajo de Struts como los
distintos elementos del framework, incluyendo las innovadoras adaptaciones del
mismo que nos ofrece la ltima versin de Struts, conocida como Struts 2. Todo
ello abordado de una manera didctica y completado con numerosos ejemplos y
prcticas que adems de ayudar al lector a comprender los conceptos le ilustrar
sobre todas las posibilidades que ofrecen los diferentes componentes del
framework.
Adems de constituir una gua til para profesionales y conocedores de la
plataforma J avaEE, el desarrollo secuencial y ordenado de los temas del libro
facilita su uso como manual de estudio en cursos de formacin donde se imparta
esta materia.
...........................................

También podría gustarte