libro struts

Upload: robertcabeza9697

Post on 10-Jul-2015

3.129 views

Category:

Documents


16 download

TRANSCRIPT

Struts2 edicin

Struts2 edicinAntonio J. Martn Sierra

A mi sobrino Hugo.

NDICEPRLOGO............................................................................................................. 13 CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR .............................................................................................. 191.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 .................................................... 352.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 JSP ......................................................................... 41 2.3 FUNCIONAMIENTO DE UNA APLICACIN STRUTS .................................. 42

CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS ......453.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 ............................................ 874.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 ....................1435.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 ............................ 1716.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 MENSAJES 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 MENSAJES 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 ......................................... 2017.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 .................................................................................. 2238.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 EJEMPLO 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 OBJETOS .................................................................................. 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 ...................... 305EXPRESIONES EL .................................................................................................. 306 ACCESO A VARIABLES DE MBITO................................................................. 307

12 STRUTS

RA-MA

OBJETOS IMPLCITOS EL .................................................................................... 308 OPERADORES EL .................................................................................................. 310

APNDICE B. LA LIBRERA DE ACCIONES ESTNDAR DE JSP (JSTL) ............................................................................................. 313INSTALACIN DE JSTL ........................................................................................ 313 UTILIZACIN DE ACCIONES JSTL .................................................................... 314 ANLISIS DE LAS PRINCIPALES ACCIONES JSTL ......................................... 314 ACCIONES GENRICAS .......................................................................................... 315 out .................................................................................................................... 315 set..................................................................................................................... 315 remove ............................................................................................................. 316 catch ................................................................................................................. 316 redirect ............................................................................................................. 317 CONTROL DE FLUJO ............................................................................................... 317 if....................................................................................................................... 317 choose .............................................................................................................. 318 foreach ............................................................................................................. 319 fortokens .......................................................................................................... 319

NDICE ALFABTICO ..................................................................................... 321

PRLOGOEl 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 JavaEE, 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 JavaEE. En los ltimos dos aos han ido apareciendo otros framework JavaEE que estn teniendo bastante aceptacin, como Spring o Java Server Faces (JSF). 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 LIBROEl 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 JavaEE, 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 DIRIGIDOPara poder comprender y utilizar los conceptos que se exponen en este libro es necesario tener conocimientos de programacin en Java y estar familiarizado con el uso de las principales tecnologas JavaEE, como son el API Servlet y las pginas JSP. 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 JavaEE 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 Java sobre plataforma JavaEE donde se incluya un mdulo de Struts, siendo de gran ayuda los ejemplos y prcticas que se incluyen.

RA-MA

PRLOGO 15

ESTRUCTURA DEL LIBROEl 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 JSP, 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 JSP, ms conocido como lenguaje EL, y de la librera de acciones estndares JSP, conocida tambin como librera JSTL.

16 STRUTS

RA-MA

MATERIAL ADICIONALLos 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 Java 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 UTILIZADASSe 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 courier para listados, tanto de cdigo Java como de etiquetado XHTML/JSP. Para destacar los comentarios dentro del cdigo se utilizar el tipo courier en cursiva, mientras que para resaltar las instrucciones importantes se emplear courier en negrita.

AGRADECIMIENTOSQuiero mostrar mi agradecimiento al equipo de Ra-Ma, que ha hecho posible que este libro salga a la luz, en especial a Luis San Jos y Jess Ramrez. Tambin quiero agradecer a Juan Garca Sanz, Gerente de Formacin de logos, a Juan de Dios Izquierdo, Jefe 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 CONTACTOEspero 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: [email protected]

1Captulo 1

LA ARQUITECTURA MODELO VISTA CONTROLADORLas 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 (Java/JavaEE, 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 JavaEE es la arquitectura Modelo Vista Controlador (MVC), la cual proporciona una clara separacin entre las distintas responsabilidades de la aplicacin.

1.1 EL PATRN MVCCuando 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 JavaEE. 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

Controlador (Servlet)

Browser

Vista (JSP)

Modelo (Clases, EJB)

BD

Fig. 2.

Esquema de una aplicacin MVC

1.1.1 El ControladorSe 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 JavaEE 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).

22 STRUTS

RA-MA

n 1 sti ge icin t pepeticin 1 peticin 2 peticin 3

Servlet 1

Servlet principal

gestin peticin 2

Servlet 2

g pe est tic in in 3

Servlet 3Fig. 3. Despacho de la gestin de peticiones entre distintos servlets

1.1.2 La VistaTal 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 JSP 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 ModeloEn 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.

RA-MA

CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 23

En una aplicacin JavaEE el modelo puede ser implementado mediante clases estndar Java o a travs de Enterprise JavaBeans.

1.2 FUNCIONAMIENTO DE UNA APLICACIN MVCUna 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.servidor url de la aplicacin (context path) url del servlet (servlet path) informacin adicional (path info)

http://www.miservidor.com /aplicacion /url_servlet /infoFig. 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

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 JavaBeans. Un JavaBean 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 JavaBean de ejemplo que permite encapsular una serie de datos asociados a una persona:public class Persona{ private String nombre; private String apellido; private int edad; public void setNombre(String nombre){ this.nombre=nombre; } public String getnombre(){ return this.nombre; } public void setApellido(String apellido){

RA-MA

CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 25

this.apellido=apellido; } public String getApellido(){ return this.apellido; } public void setEdad(int edad){ this.edad=edad; } public int getEdad(){ return this.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 JSP 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 DescripcinPara 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

DesarrolloLos mensajes manejados por la aplicacin sern almacenados en una tabla cuya estructura se indica en la figura 6.

Nombre Campo remitente destinatario textoFig. 6.

Tipo Datos cadena de texto cadena de texto cadena de texto

Tabla para el almacenamiento de mensajes

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 JavaBean 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 JSP (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.

ListadosA continuacin presentamos el cdigo de cada uno de los elementos de la aplicacin. Clase Mensajepackage javabeans; public class Mensaje { private String remite; private String destino; private String texto; public Mensaje(){} //constructor que permite crear un objeto //Mensaje a partir de los datos del mismo public Mensaje(String remite, String destino, String texto){ this.remite=remite; this.destino=destino; this.texto=texto; } public void setRemite(String remite){ this.remite=remite; }

28 STRUTS

RA-MA

public String getRemite(){ return this.remite; } public void setDestino(String destino){ this.destino=destino; } public String getDestino(){ return this.destino; } public void setTexto(String texto){ this.texto=texto; } public String getTexto(){ return this.texto; } }

Clase Controladorpackage servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; import javabeans.*; import modelo.*; public class Controlador extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String op=request.getParameter("operacion"); //acceso a la pgina de envo de mensajes if(op.equals("envio")) response.sendRedirect("envio.jsp");

//grabacin de un mensajeif(op.equals("grabar")){ Mensaje men=(Mensaje)request.getAttribute("mensa"); Operaciones oper=new Operaciones(); oper.grabaMensaje(men); response.sendRedirect("inicio.htm"); }

RA-MA

CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 29

//acceso a la pgina de solicitud de mensajes if(op.equals("muestra")) response.sendRedirect("mostrar.htm");

//acceso a la lista de mensajes del usuarioif(op.equals("ver")){ Operaciones oper=new Operaciones(); ArrayList mensajes=oper.obtenerMensajes( request.getParameter("nombre")); request.setAttribute("mensajes",mensajes); RequestDispatcher rd=request. getRequestDispatcher("/ver.jsp"); rd.forward(request,response); } } }

Clase Operacionespackage modelo; import java.sql.*; import javabeans.*; import java.util.*; public class Operaciones {

//mtodo comn para la obtencin //de conexionespublic Connection getConnection(){ Connection cn=null; try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); cn=DriverManager.getConnection("jdbc:odbc:mensajes"); } catch(Exception e){e.printStackTrace();} return cn; } public ArrayList obtenerMensajes(String destino){ Connection cn=null; ArrayList mensajes=null; Statement st; ResultSet rs; try{ cn=getConnection(); st=cn.createStatement();

30 STRUTS

RA-MA

String tsql; tsql="select * from mensajes where destinatario='"+ destino+"'"; rs=st.executeQuery(tsql); mensajes=new ArrayList(); //para cada mensaje encontrado crea un objeto //Mensaje y lo aade a la coleccin ArrayList while(rs.next()){ Mensaje m=new Mensaje(rs.getString("remitente"), rs.getString("destinatario"), rs.getString("texto")); mensajes.add(m); } cn.close(); } catch(Exception e){e.printStackTrace();} return(mensajes); } public void grabaMensaje(Mensaje m){ Connection cn; Statement st; ResultSet rs; try{ cn=getConnection(); st=cn.createStatement(); String tsql;

//a partir de los datos del mensaje construye //la cadena SQL para realizar su inserintsql="Insert into mensajes values('"; tsql+=m.getDestino()+"','"+ m.getRemite()+"','"+ m.getTexto()+"')"; st.execute(tsql); cn.close(); } catch(Exception e){e.printStackTrace();} } }

inicio.htm

RA-MA

CAPTULO 1. LA ARQUITECTURA MODELO VISTA CONTROLADOR 31



Enviar mensaje

Leer mensajes

mostrar.htm

Introduzca su nombre:

envio.jsp envio

32 STRUTS

RA-MA

Generacin de mensajes

Datos del mensaje:

Introduzca destinatario:

Introduzca remitente :

Introduzca texto :

ver.jsp ver Mensajes para RemitenteMensaje


RA-MA

CAPTULO 3. DESARROLLO DE UNA APLICACIN CON STRUTS 85

listado.jsp JSP Page Listado de Llamadas Telfono destino Duracin (segundos) Tarifa Coste Fecha

........

processPath(){..} processPreprocess(){..}1 2 3 4 5 6 7 8 9

106 STRUTS

RA-MA

A partir de fecha:

4.2.2 Clase LookupDispatchActionSe 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

ApplicationResource.properties key1=clave_metodo1 key2=clave_metodo2 Recuperacin de la clave

Tabla Map clave_metodo1 clave_metodo2 nombre_metodo1 nombre_metodo2

2

3

Recuperacin del nombre de mtodo

parametro=key1 direccion.do? parametro=key2

1

Objeto LookUpDispatchAction

4:

Llamada al mtodo

public ActionForward nombre_metodo1(...){..}

public ActionForward nombre_metodo2(...){..}

:

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

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 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 servlets; import javax.servlet.http.*; import org.apache.struts.action.*; import org.apache.struts.actions.*; import javabeans.*; import modelo.*; import java.util.*; public class ListadoAction extends DispatchAction { public Map getKeyMethodMap(){ //definicin de mapa de mtodos con sus // correspondientes claves Map mp=new HashMap(); mp.put("opcion.todas","todas"); mp.put("opcion.portipo","portipo"); mp.put("opcion.porfecha","porfecha"); return mp;

110 STRUTS

RA-MA

} public ActionForward todas(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { OpcionesForm of=(OpcionesForm)form; GestionLlamadas gl=getGestionLlamadas(request); request.setAttribute("llamadas", gl.getTodasLlamadasTelefono(of.getNumero())); return mapping.findForward("listado"); } public ActionForward portipo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { OpcionesForm of=(OpcionesForm)form; GestionLlamadas gl=getGestionLlamadas(request); request.setAttribute("llamadas", gl.getLlamadasTelefonoPorTipoTarifa( of.getNumero(),of.getTipo())); return mapping.findForward("listado"); } public ActionForward porfecha(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { OpcionesForm of=(OpcionesForm)form; GestionLlamadas gl=getGestionLlamadas(request); request.setAttribute("llamadas", gl.getLlamadasTelefonoApartirFecha( of.getNumero(),of.getFecha())); return mapping.findForward("listado"); } private GestionLlamadas getGestionLlamadas( HttpServletRequest request){ String driver=this.getServlet(). getServletContext().getInitParameter("driver"); String cadenaCon=this.getServlet().

RA-MA

CAPTULO 4. ANLISIS DEL API DE STRUTS 111

getServletContext().getInitParameter("cadenaCon"); return new GestionLlamadas(driver,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: JSP Page Opciones para el listado de llamadas Seleccione nmero de telfono:




Seleccione tipo de llamadas:

112 STRUTS

RA-MA

Todas Seleccione Tipo: A partir de fecha:

4.2.3 Clase MappingDispatchActionSe 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 asociados a la misma subclase de MappingDispatchAction como peticiones distintas deba gestionar el objeto. Utilizando el atributo parameter del elemento 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).struts-config.xml Recuperacin del nombre de mtodo

2

direccion1.do direccion2.do

1

Objeto MappingDispatchAction

3:

Llamada al mtodo

public ActionForward metodo1(...){..}

public ActionForward metodo2(...){..} :

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: Aadir elemento Eliminar elemento Recuperar contenido

114 STRUTS

RA-MA

Para que las tres peticiones provoquen la ejecucin del objeto GestionCarritoAction deberamos registrar los siguientes elementos en el archivo struts-config.xml:

Los valores indicados en el atributo parameter de cada elemento 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 DescripcinLa 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

DesarrolloLa 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 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

ListadoSeguidamente mostraremos el cdigo de los nuevos elementos desarrollados en esta prctica, as como las modificaciones realizadas en los ya creados. struts-config.xml

RA-MA

CAPTULO 4. ANLISIS DEL API DE STRUTS 117

GestionLlamadas.javapackage modelo; import java.sql.*; import java.util.*; import javabeans.*; import java.text.*; public class GestionLlamadas { Datos dt; public GestionLlamadas(String driver, String cadenacon) { dt=new Datos(driver,cadenacon); } public ArrayList getLlamadas( String password){ String query = "select * from llamadas where "; query+="telefono in (select telefono from telefonos where "; query+="password ='"+password+"') order by telefono";

118 STRUTS

RA-MA

return getListado(query); } //mtodo auxiliar de apoyo al anterior private ArrayList getListado(String sql){

//se utiliza para poder aplicar el formato //de fecha europeoDateFormat feuropa=DateFormat.getDateInstance( DateFormat.SHORT,Locale.getDefault()); ArrayList llamadas= new ArrayList(); try{ Connection cn=dt.getConexion(); Statement st =cn.createStatement(); ResultSet rs = st.executeQuery(sql); while(rs.next()){ LlamadaBean llamada=new LlamadaBean(); llamada.setTelefono(rs.getInt("telefono")); llamada.setDestino(rs.getInt("destino")); llamada.setDuracion(rs.getInt("duracion")); llamada.setTarifa(this.getTarifa( rs.getInt("idtipotarifa"))); llamada.setCoste(rs.getDouble("coste")); llamada.setFecha(feuropa.format( rs.getDate("fecha"))); llamadas.add(llamada); } dt.cierraConexion(cn); } catch(Exception e){ e.printStackTrace(); } finally{ return llamadas; } } public double getFactura(String password){ String query = "select sum(coste) as total from llamadas where "; query+="telefono in (select telefono from telefonos "; query+=" where password ='"+password+"')"; double total=0.0;

RA-MA

CAPTULO 4. ANLISIS DEL API DE STRUTS 119

try{ Connection cn=dt.getConexion(); Statement st =cn.createStatement(); ResultSet rs = st.executeQuery(query); if(rs.next()){ total=rs.getDouble("total"); } dt.cierraConexion(cn); } catch(Exception e){ e.printStackTrace(); } finally{ return total; } } private String getTarifa(int id){ String tarifa=null; try{ Connection cn=dt.getConexion(); String query = "select nombretarifa from tarifas "; query +="where idtipotarifa="+id; Statement st =cn.createStatement(); ResultSet rs = st.executeQuery(query); if(rs.next()){ tarifa=rs.getString("nombretarifa"); } dt.cierraConexion(cn); } catch(Exception e){ e.printStackTrace(); } finally{ return tarifa; } } }

OpcionesAction.javapackage servlets;

120 STRUTS

RA-MA

import javax.servlet.http.*; import import import import import org.apache.struts.action.*; org.apache.struts.actions.*; javabeans.*; modelo.*; java.util.*;

public class OpcionesAction extends MappingDispatchAction { public ActionForward factura( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { HttpSession sesion=request.getSession(); ValidacionForm vf=(ValidacionForm)sesion. getAttribute("ValidacionForm"); GestionLlamadas gl=getGestionLlamadas(request); request.setAttribute("precio", gl.getFactura(vf.getPassword())); return mapping.findForward("vistafactura"); } public ActionForward numeros(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //el FormBean ValidacionForm contiene los telfonos //asociados al usuario return mapping.findForward("vistanumeros"); } public ActionForward detalles(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { HttpSession sesion=request.getSession(); ValidacionForm vf=(ValidacionForm)sesion. getAttribute("ValidacionForm");

RA-MA

CAPTULO 4. ANLISIS DEL API DE STRUTS 121

GestionLlamadas gl=getGestionLlamadas(request); request.setAttribute("llamadas", gl.getLlamadas(vf.getPassword())); return mapping.findForward("vistadetalles"); } private GestionLlamadas getGestionLlamadas( HttpServletRequest request){ String driver=this.getServlet(). getServletContext().getInitParameter("driver"); String cadenaCon=this.getServlet(). getServletContext().getInitParameter("cadenaCon"); return new GestionLlamadas(driver,cadenaCon); } }

opciones.jsp JSP Page .td{margin-left:0px} Opciones para el usuario Mostrar sus numeros

122 STRUTS

RA-MA

Facturacin total del usuario Detalles de llamadas

nomeros.jsp JSP Page

Este usuario tiene contratados los siguientes nmeros:




Seleccione tipo de llamadas:
Todas Seleccione Tipo: Normal Reducida Super reducida

RA-MA

CAPTULO 5. LIBRERAS DE ACCIONES JSP DE STRUTS 161

A partir de fecha:

listado.jsp JSP Page Listado de Llamadas Telfono destino Duracin (segundos) Tarifa Coste

162 STRUTS

RA-MA

Fecha

PRCTICA 5.2. ENVO Y VISUALIZACIN DE MENSAJES DescripcinSe 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.

DesarrolloAdems 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.

ListadoSeguidamente 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 JSP DE STRUTS 163

struts-config.xml

MensajeForm.javapackage javabeans; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.*; public class MensajeForm extends ActionForm {

164 STRUTS

RA-MA

private String remite; private String destino; private String texto; public MensajeForm(){} //constructor que permite crear un objeto //Mensaje a partir de los datos del mismo public MensajeForm(String remite, String destino, String texto){ this.remite=remite; this.destino=destino; this.texto=texto; } public void setRemite(String remite){ this.remite=remite; } public String getRemite(){ return this.remite; } public void setDestino(String destino){ this.destino=destino; } public String getDestino(){ return this.destino; } public void setTexto(String texto){ this.texto=texto; } public String getTexto(){ return this.texto; } }

EnviarAction.javapackage servlets; import javax.servlet.http.*; import org.apache.struts.action.*; import javabeans.*; import modelo.*; public class EnviarAction extends Action { public ActionForward execute(ActionMapping mapping,

RA-MA

CAPTULO 5. LIBRERAS DE ACCIONES JSP DE STRUTS 165

ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { MensajeForm men=(MensajeForm)form; Operaciones oper=new Operaciones(); oper.grabaMensaje(men); return mapping.findForward("grabado"); } }

RecuperarAction.javapackage servlets; import javax.servlet.http.*; import org.apache.struts.action.*; import java.util.*; import javabeans.*; import modelo.*; public class RecuperarAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { Operaciones oper=new Operaciones(); ArrayList mensajes=oper. obtenerMensajes(request.getParameter("nombre")); //si hay mensajes se visualizan if(mensajes!=null&&mensajes.size()>0){ request.setAttribute("mensajes",mensajes); return mapping.findForward("visualiza"); } else{ return mapping.findForward("sinmensajes"); } } }

166 STRUTS

RA-MA

Operaciones.javapackage modelo; import java.sql.*; import javabeans.*; import java.util.*; public class Operaciones { //mtodo comn para la obtencin //de conexiones public Connection getConnection(){ Connection cn=null; try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); cn=DriverManager.getConnection("jdbc:odbc:mensajes"); } catch(Exception e){e.printStackTrace();} return cn; } public ArrayList obtenerMensajes(String destino){ Connection cn=null; ArrayList mensajes=null; Statement st; ResultSet rs; try{ cn=getConnection(); st=cn.createStatement(); String tsql; tsql="select * from mensajes where destinatario='"+destino+"'"; rs=st.executeQuery(tsql); mensajes=new ArrayList();

//para cada mensaje encontrado crea un objeto //Mensaje y lo aade a la coleccin ArrayListwhile(rs.next()){ MensajeForm m=new MensajeForm( rs.getString("remitente"), rs.getString("destinatario"), rs.getString("texto")); mensajes.add(m); } cn.close();

RA-MA

CAPTULO 5. LIBRERAS DE ACCIONES JSP DE STRUTS 167

} catch(Exception e){e.printStackTrace();} return(mensajes); } public void grabaMensaje(MensajeForm m){ Connection cn; Statement st; ResultSet rs; try{ cn=getConnection(); st=cn.createStatement(); String tsql; //a partir de los datos del mensaje construye //la cadena SQL para realizar su inserin tsql="Insert into mensajes values('"; tsql+=m.getDestino()+ "','"+m.getRemite()+ "','"+m.getTexto()+"')"; st.execute(tsql); cn.close(); } catch(Exception e){e.printStackTrace();} } }

inicio.jsp

Enviar mensaje

168 STRUTS

RA-MA

Leer mensajes

envio.jsp Generacin de mensajes

Datos del mensaje:

Introduzca destinatario:

Introduzca remitente :

Introduzca texto :

RA-MA

CAPTULO 5. LIBRERAS DE ACCIONES JSP DE STRUTS 169

mostrar.htm

Introduzca su nombre:

ver.jsp Mensajes para RemitenteMensaje

Inicio

nomensajes.jsp Lo siento, no tiene mensajes



Inicio

6Captulo 6

VALIDACIN DE DATOS DE USUARIOLa 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 VALIDADORLa utilizacin de validadores en una pgina JSP 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 validatorEl 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 :

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 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 configuracinAdems 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.XMLA 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: :

174 STRUTS

RA-MA

Cada una de estas reglas de validacin se declaran mediante un elemento , 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.XMLEn 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: :

Para cada formulario que se desee validar se definir un elemento , 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 mediante el elemento . Ms adelante analizaremos las distintas reglas de validacin personalizadas proporcionadas por Struts y la forma de utilizarlas.

6.1.3 Clase ValidatorFormA la hora de definir la clase JavaBean 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.propertiesComo 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 VALIDADORESLa 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 strutsconfig.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 validatorrules.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 ValidatorFormLa 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:import org.apache.struts.validator.*; public class ValidacionForm extends ValidatorForm { //datos miembro private String usuario; private String password;

//mtodos de accesopublic String getUsuario() { return usuario; } public void setUsuario(String nombre) { this.usuario = nombre; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

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 validacinPara 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 asociado al mismo, elemento que deber estar definido dentro del elemento que se incluye a su vez en el elemento raz del documento:

RA-MA

CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 179

:

En el interior de incluiremos dos elementos , uno por cada campo que queremos validar. Cada elemento 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 incluir adems un elemento 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 , un elemento puede incluir opcionalmente los elementos , , y , 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 . Si el mensaje de error requiere nicamente un argumento, puede utilizarse o indistintamente. Con todo ello, el archivo validation.xml del ejemplo que estamos analizando quedara:

6.2.3 Habilitacin de la validacin en clienteSiempre 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 JavaScript (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 JavaScript 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: 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 JavaScript 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: Formulario de autenticacin Usuario: Password:

182 STRUTS

RA-MA


Registrese

6.2.4 Mensajes de errorEl 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 .

RA-MA

CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 183

Fig. 30.

Mensaje de error de validacin

6.3 VALIDADORES PREDEFINIDOS DE STRUTSYa 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 minlengthEste validador comprueba que el valor numrico suministrado en un campo sea mayor o igual a una determinada constante. Adems de los subelementos , el elemento utilizado en la declaracin de este validador en validation.xml deber incluir un subelemento en el que se indique la constante con la que se comparar el valor del campo. La estructura de este elemento es: nombre valor

184 STRUTS

RA-MA

donde contiene el nombre de la constante (en el caso de minlength el nombre de la variable ser el mismo, minlength) y 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: minlength 18

En este validador vemos cmo el mensaje de error requiere de dos argumentos, el nombre del campo y el valor mnimo.

6.3.2 maxlengthSu estructura es igual a la de minlength, validando el campo indicado en el atributo property de si su valor es igual o inferior a la constante indicada en el elemento . El siguiente ejemplo establece que el valor del campo limite debe ser igual o inferior a 600: maxlength 600

En el ejemplo anterior vemos cmo en el mismo elemento 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 permite indicar el tipo de validador al que est asociado el argumento.

6.3.3 byte, short, integer, long, float y doubleMediante 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:

6.3.4 intRangeEl 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 llamados max y min. La siguiente regla permite verificar que el valor del campo nota est comprendido entre 1 y 10: min 1 max 10

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 doubleRangeAl 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 es exactamente igual a la de intRange.

6.3.6 dateComprueba que el valor del campo tiene un formato de fecha vlido:

Opcionalmente el elemento 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: datePattern dd/MM/yyyy

RA-MA

CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 187

6.3.7 maskA 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 Java. Por ejemplo, la siguiente regla de validacin establece que el contenido del campo url debe ser la direccin de un dominio .com: mask www\..+\.com

6.3.8 emailOtro 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:

6.4 MENSAJES DE ERROR PERSONALIZADOSSi 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 . 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 de , 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:

Los argumentos indicados en se referirn en estos casos al nuevo mensaje definido.

PRCTICA 6.1. VALIDACIN DE LOS CAMPOS DE LA PGINA DE REGISTRO DescripcinUtilizando 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

DesarrolloSegn 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 Java, 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

ListadoSeguidamente 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:RegistroForm.nombre="nombre" RegistroForm.apellidos="apellidos" RegistroForm.usuario="nombre" RegistroForm.password="password" RegistroForm.edad="edad" RegistroForm.email="email" RegistroForm.password.min="4"

validation.xml

RA-MA

CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 191

minlength 4

registro.jsp Registro de usuarios

192 STRUTS

RA-MA

Nombre: Apellidos: Usuario: Password: Edad: Email:


RA-MA

CAPTULO 6. VALIDACIN DE DATOS DE USUARIO 193

6.5 VALIDACIONES PERSONALIZADASEn 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.HttpServle