You are on page 1of 297
Antonio J. Martin Sierra (0) Alfaomega ced KK STRUTS Antonio J. Martin Sierra Alfaomega 4 Ra-Ma’ ‘Martin, Antonio surts Primera EdiciOn ‘Alfaomega Grupo Editor, S.A. de CY, ISBN: 978-970. ae 154 Formato: 17% 23 cm S-1414-6 edicign original publienda POF RAMA Editor ‘ (A Eaitorial jitorial, Madrid, Espaita ie treo J. Matin ct 34-7897 795541, A: ise echos osevaos © ico, septiembre 2008 primera edicion: Alfsomet os . Eaitor, Méx GN. ‘0 2008 Alfaomes po Edito gore 1139, Col: alvalle Meto0, shoo DE ‘Miembro de Ja Cara Registro No. 2317 Pig. Webs ge mx Pama: breriaptagoras@auiaomeee ‘com.mx ISBN: 978-970-15-1414-6 Nacional de la Industria Editorial Mexicana sn obra es propiedad intelectual de sa 6 se su autor y ls derechos de publicaci6 Fa mts cf Poi Teme Parc 3 en lengua espafiola sito ier et el pope Ge ees del oO. cal pa ee A mntenida en esta obra tiene un fin exclusi jamente didctico oy sua aie cae oink Las eee eae de contol Sac : a sesgurtamen (Cec eu er responsable Teaser oc SSOta apna ne .que pudiera dase. Editor, S.A. de C.V. ~ Pitigoras Fax: (52-55) 1139, 55752400 290. 199, Col Det Yale Mang DB Ami sobrino Hugo. en CAPITULO 1. LA ARQUITECTI CONTROLADOR 1.1 EL PATRON Mv. 1.1.1 EL ConTROLADOR 1.1.2La Vista... L1.3ELMopeto... 5 1.2 FUNCIONAMIENTO DE UNA APLICACION MVC... CAPITULO 2. EL FRAMEWORK STRUTS 2.1 FUNDAMENTOS DE STRUTS..... 2.2 COMPONENTES DE STRUTS.. 2.2.1 ARCHIVOS DE CONFIGURACI 2.2.2 EL API DE STRUTS....... 2.2.3 LIBRERIAS DE ACCIONES JSP. ; 2.3 FUNCIONAMIENTO DE UNA APLICACION STRUTS ww.nenonnssnnnsenen 42 'URA MODELO VISTA CAPITULO 3. DESARROLLO DE UNA APLICACION CON STRUTS.....45 3.1 DESCARGA E INSTALACION DEL FRAMEWORK STRUTS 4s 3.2 APLICACION PRACTICA PARA BREE aCIGN Y REGISTRO DE USUARIOS. 3.2.1 FUNCIONAMIENTO DE neat i 3,2,2 ESQUEMA DE LA APLICACION.... 3.2.3 CONSTRUCCION DE LA APLICACION .. icacion Web Struts . fel servlet ActionServiet datos de usuario: las clases ValidarForm y Reg *ién del Modelo... peticiones: Las clases ValidarAction y estructura de una a 3.23.1 3.2.3.2 Registro 3.2.3.3 Capture de 3.2.34 Implementac! 3.23.5 Procesamiento de RegistrarAction. = 3.2.3.6 Objetos forward. ‘globales 5.2.3.7 Las paginas de Ia vist ~ capiTuLo 4. ANALISIS DEL API DE STRUTS. 4,1 PROCESAMIENTO DE UNA PETICION: CLASES ACTION: REQUESTPROCESSOR o-- SERVLET ¥ 42 CLASES DE ACCION 42.1 CLASE DISPATCHACTION or 422.2. CLASE LOOKUPDISPATCHACTION 42.3 CLASE MAPPINGDISPATCHACTION 4.2.4 CLASE ACTIONFORM. 424.1 Ciclo de vida de un ActionForm: 42.5 ACTIONERRORS ¥ ACTIONMESSAGE .. 43 CONTROL DE EXCEPCIONES EN STRUTS... |4.3,1 GESTION DECLARATIVA DE EXCEPCIONES... pa 5 IMPLEMENTACION DE LA GESTION DECLARATIVA DE EXCEPCIO} 13,3 CLASES PERSONALIZADAS PARA LA GESTION DE EXCEPCIONES He CAPITULO 5. LIBRERIAS D) 5 E ACCI ple ae TONES JSP DE STRUTS.... 5.2.7 REDIRECT... S2.8TTERATE,, 6:1.2, ARCHIVOS DE CONFIGURACION..... < 168 6.1.2.1 validator-rules xm een. es 6.1.2.2 validation xml... anes a 170 6:1.3 CLASE VALIDATORFORM........ m 6.1.4 ARCHIVO APPLICATIONRESOURCE.PROPERTIES... : 172 62 UTILIZACION DE VALIDADORES ..... 6.2.1 CREACION DE LA CLASE VALIDATORFORM..... 6.2.2 DEFINICION DE LOS CRITERIOS DE VALIDACION 6.2.3 HABILITACION DE LA VALIDACION EN CLIENTE 6.2.4 MENSAJES DE ERROR tues 6.3 VALIDADORES PREDEFINIDOS DE STRUTS. 6.3.1 MINLENGTH .. 6.3.2 MAXLENGTH. 6.3.3 BYTE, SHORT, INTEGER, LONG, FLOAT ¥ DOUBLE 6.3.4 INTRANGE 6.3.5 FLOATRANGE Y DOUBLERANGE.... 6.5 VALIDACIONES PERSONALIZADAS.. 6.5.1 SOBRESCRITURA DEL METODO VALIDATE() 6.5.2 CREACION DE VALIDADORES PERSONALIZADOS.. 6.5.2.1 Implementacién del método de validacion 6.5.2.2 Registro del validador. 6.5.2.3 Mensajes de error 6.5.2.4 Utilizacién del validador. s UNA APLICACI 7.2 CREACION DE EN PLANTILLA: 7.3 DEFINICIONES 7131.1 CREACION DEUNA DEFINICION 7.3.1.1 Definiciones base - 7.3.1.2 Definiciones derivadas.. 7.3.2 PAGINAS DE APLICACION. CAPITULO 8. STRUTS 2 .eosere $.1 COMPONENTES DE STRUTS 2 8.1.4 LIBRERIAS DE ACCIONES 8.1.5 ARCHIVO DE CONFIGURACION STRUTS.XML. e BENEFICIOS DEL USO DE STRUTS BERN DEUNA APLICACION DE EJEMPLO DE STRUTS2...... | DESCARGA DEL PAQUETE DE DISTRIBUCION DE STRUTS 2 ax seteieenennenn : ; : APENDICE A. EL LENGUAJE DE EXPRESIONES DE JSP SRAM Se 84.1 DECLARACION Dex DrTtancertog 8.4.2 ASIONACON DE Un 8.43 InvECCION D 84.4 InteRcern INTERCEPTOR 4 Uma accuom x DE DEFENDENCIA ; IORES PERSONAL IZADOS 8.4.4.1 El método intercept() 8.5 LA LIBRERIA DE ACCIONES STRUTs-TAce 85.1 EL STACK DE omETos 8.5.2 ACCIONES DE MANIPULACION os 8.5.2.1 bean 8522 Datos param 8.5.2.3 property y 85.24 push : 85.25 set 8.5.3 ACCIONES DE CONTROL ‘ 853.1 if iterator CCIONES UL 8.5.4.1 form 8.5.4.2 textfield 8.5.4.3 password 8.5.44 textarea 8.5.4.5 submit 8.5.4.6 radio. 8.5.4.7 checkbox 8.5.4.8 checkboxList 8.5.4.9 select 8.5.4.10 actionerror... 8.6 VALIDADORES .. 8.6.1 VALIDADORES PREDEFINIDOS i 8.6.2 UTILIZACION DE VALIDADORES EN UNA APLICACION, 8.7 ANOTACIONES .. cea EXPRESIONES EL... 7 ACCESO A VARIABLES DE AMBITO. OBJETOS IMPLICITOS EL... APENDICE B. LA LIBRERIA DE ACCIONES EST. PENIS? (IST rome ANDAR. INSTALACION DE JSTL- UTILIZACION DE ACCIONES ISTE [ANALISIS DE LAS PRINCIPALES ‘ACCIONES JSTL. iNDICE ALFABETICO El rapido crecimiento que ha experimentado « uplicasiones Web ha’ ido paralelo con el aumento « funcionalidades que los usuarios solicitan a estas aplicacio los Gltimos la d nes, Esto ha supuesto al mismo tiempo un incremento en la com desarrollos, provocando la proliferacién de lengua} orientadas a facilitar el trabajo de los programadores . herramientas y Una de esas “tecnologias” es Struts. Struts se enmarca dentro del del desarrollo de aplicaciones para Internet bajo arquitectura J2EE. si bien, no se trata de un elemento mas de dicha arquitectura sino de un marco d ayuda a los programadores en la creacién de aplicaciones fe entome, Teduciendo Ia complejidad y el tiempo de los desarrollos y, sobre todo, haciéndolos mucho més robustos y fiiciles de mantener. rabajo que Struts fue lanzado por primera vez al mercado en el aio 2002 y desde ese mismo momento tuyo una enorme aceptacién en la comunidad de desarrolladores, hasta el punto que hoy en dia es, con diferencia, el framework més utilizado en la construccién de aplicaciones J2EE. En los iltimos dos afios han ido apareciendo otros framework J2EE que estn teniendo bastante aceptacién, como Spring o Java Server Faces (JSF). Pero ‘este hecho, lejos de perjudicar a Struts, ha propiciado su evolucién y su adaptacién a los requerimientos de las aplicaciones modernas. Ademés, la utilizacién de Struts no es incompatible con estos nuevos frameworks, siendo posible su integracién con Jos anteriormente mencionados de cara a aumentar la potencia de los desarrollos. oBseTIVO DEL LIBRO a5 oe os pretend con ests HibeO =: PESAGSRN SI ISaaa 4 1 objetivo 08 Framework Struts y guile en el desarog elementos que resentan una serie de pricticas que serviray » aplicaciones, pars © atados y mostrarle la forma en la que los rentes deben ser utilizados en los desarrollos. ‘var el estudio de este libro el lector estaré capaci eb bajo arquitectura J2EE, totalmente estr is potencia que le offece Struts, incluidas las nye de trabajo que se incluye en la ditima version Struts 9. ‘compon ‘Asi pues, al final aplicaciones Wé utilizando toda | es y metodologia construir robustas, prest A QUIEN VA DIRIGIDO Para poder eomprender y utilizar los conceptos que se exponen en ¢ iro es necesario tener conocimientos de programacién en Java y est familierizado con el uso de las principales tecnologias J2EE, como son el Servlet y las paginas JSP. Este libro sera por tanto de gran utilidad a aquellos programadores que se vayan a enfrentar al reto de desarrollar grandes aplicaciones empresari en este entorno, pues es en estas circunstancias donde la utilizacién de framework con las prestaciones de Struts se hace mds que necesaria, EI libro puede ser utilizado también por estudiantes y, en general, cualquier conocedor de Ia plataforma J2EE que desee ampliar sus conocimier adentrindose en el andlisis de las posibilidades que ofrece Struts, Por su enfoque didactico y prictico, este libro puede ser utilizado manual de estudio en cursos de programacién en Java sobre plataforma donde se incluya un médulo de Struts, siendo de gran ayuda los ejemy pricticas que se incluyen. : tee ESTRUCTURA DEL LIBRO i libro estdorganizado en ocho captulosy dos Al ser et principi S, Presentando general de la En los capitulos 4 y 5 analizaremos en detalle los dos piezas que componen este framework: el API de Struts y las libr ISP, respectivamente. andes tipos de Los capitulos 6 y 7 servirén para profundizar en dos de las caracteristicas avanzadas mas interesantes de Struts. En concreto, el capitulo 6 aborda el estudio de los validadores, con cuya ayuda podremos evitar la codificacién de grandes cantidades de cédigo dedicadas inicamente a comprobar los datos suministrados por el usuario, mientras que el capitulo 7 analiza el uso de las plantillas (tiles) para Ja reutilizacién de cédigo en las vistas de una aplicacién El capitulo 8 nos presenta las caracteristicas de la nueva versién del framework: Struts 2, analizando la arquitectura planteada para e! desarrollo de las aplicaciones, asi como Ia funcionalidad, utilizacién y configuracién de los nuevos componentes del framework. Por tiltimo, los apéndices A y B nos presentan dos elementos que, sin eet Capleatan pexincat con ly ayaa a mejorar los desarrollos; concretamente se trata del lenguaje de expresiones para JSP, mas conocido como lenguaje EL, y de la libreria de acciones estindares JSP, de modo que si J abrir directamente los proyectos y prob 1s, cada proyecto incluye una carpeta con‘ lose etl utilizados en otro entornd, ‘onamien funciona eet fuente a fin de que CONVENCIONES UTILIZADAS convenciones a lo largo del libro: Se han utilizado las siguiente = Uso de megrita para resaltar ciertas definiciones © puntos importantes @ tener en cuenta. Puntos = Utilizacién de cursiva para métodos y propiedades de objetos y atributos de etiquetas, asi como para presentar el formato. utiizacién de algiin elemento de cédigo. i Empleo de estilo courier para listados, tanto de cédigo J; a como de etiquetado XHTML/JSP. Para destacar los comentarios — dentro del cédigo se utilizaré el tipo courier en cursive mientras que para resaltar las instrucciones importantes empleard courier en negrita. : AGRADECIMIENTOS Quiero mostrar mi agradecimiento al equipo de Ra-Ma, que | posible que este libro salga a la luz, en especial a Luis San José y Tests R También quiero agradecer a Juan Garcia Sanz, Gerente de Formac lowes, lun de Dis Iuiero, Jefe de Estudios de CICE.y a tor de Synerom, su apoyo y esfuerzo en la difusién de mis libros. RAMA etn DIRECCION DE CONTACTO Espero que este libro resulte de utilidad al lector, integrar el framework Struts en sus Y pueda ayudarle a y los y a poder sacar partido a todas las Si desea realizar alguna cor msulta u observacién, puede contactar conmigo a través de la siguiente direccion de correo electronico: ajms66@gmail.com Capitulo 1 LA ARQUITECTURA MODELO VISTA CONTROLADOR Las aplicaciones Web estin organizadas capas, donde la capa cliente, implementada medi misién la captura de datos de usuario y su envio a la capa presentacién de resultados proc constituye el verdadero mic! procesamiento de los datos de usuario y de la a la capa cliente. Durante este proceso, la capa in la capa de datos para el almacenamiento y recupe : por la aplicacién (figura 1), Capa Capa Capa Cliente envio de datos intermedia sem ins y lenguajes que 10s programadores ti Son muchas Ts ee See cpa interme aes ; disposicién para acomelet © er etc.). No obstante, de cara a affontar eon g HHP, ASP.NE" jo establecer un modelo o esquema Web (Java/J2EE, PI . jeoer n ‘su implementacion, Se er gees de bloques 0 compen te, a Ba estuturar eta HPS nas funciones bien defnidas dentro de la apicag uno de estos i iente al resto. pueda desarrollarse de manera independiente al res' idad, el mas utilizado temas y, con toda seguridad, a ee vee vila J2EE, es la arquitectura Modelo Vista Contro) seas le Fo pe ee responsabilidades de la aplicacion. 1.1 EL PATRON MVC Modelo Vista Controlador nos refer; .do hablamos de arquitectura anda dediseno que especifica cémo debe ser estructurada una aplicacién, je sapas que van a componer Ia misma y a funcionalidad de cada una, : Segiin este patrén, la capa intermedia de una aplicacién Web puede ser ida en tres grandes bloques funcionales: = Controlador = Vista * Modelo En Ia figura 2 se muestra esta arquitectura para el caso de una aplicacién desarrollada con tecnologias J2EE. En ella podemos ver como se relacionan est tres bloques funcionales entre si, su interaccién con el resto de las capas de | aplicacién y la tecnologia con la que estan implementados. ae Seguidamente vamos a analizar detalladamente cada uno de estos bl Presentando las caraeteristicas de cada uno de ellos, funcionalidades tecnologia empleada en el desarrollo de cada uno de ellos. ’ VISTA CONTROLADOR Ns . | sata | (Cue, == | Fig.2. Esquema de una aplicacin MVC 1.1.1 El Controlador Se puede decir que el Controlador es el “cerebro” de la apt en desde el cliente son di las peticiones a la capa intermedia que se realic al Controlador, cuya mision es determinar las acciones a realizar par estas peticiones ¢ invocar al resto de los componentes de la aplic Vista) para que realicen las acciones requeridas en ca: también de la coordinacién de todo el proceso. da ca Por ejemplo, en el caso de que una peticién requiera enviar como respue: al cliente determinada informacién existente en una base de datos, el Controlador solicitara los datos necesarios al modelo y, una vez recibidos, se los proporeionari a la Vista para que ésta les aplique el formato de presentacién correspondiente y envie la respuesta al cliente. La centralizacién del flujo de peticiones en el Controlador proporciona varias ventajas al programador, entre ellas: = Hace que el desarrollo sea mas sencillo y limpio. "= Facilita el posterior mantenimiento de la aplicacién haciéndola mas escalable. = Facilita la detecci6n de errores en el codigo. En aplicaciones J2EE 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 peticién (figura 3). Fig.3. _Despacho de la gestin de peticiones entre distintos servlets 1.1.2 La Vista ir Vista es la en Tal y como se puede deducir de su nombre, la la encargada de generar las Sas (habitualmente XHTML) que deben ser enviadas al cliente. Cuando esta respuesta tiene que incluir datos proporcionados por el Controlador, ¢ cédigo XHTML de la pigina no serd fijo si no que deberd ser generado de forma dinémica, por lo que su implementacién correrd a cargo de una pagina JSP. Las paginas JSP resultan mucho més adecuadas para la generacién de las vistas que los servlets pues, al ser documentos de texto, resulta sencilla la inclusién_ de bloques estaticos XHTML y pueden ser facilmente mantenibles Por disefiadores Web con escasos conocimientos de programacién. Cuando la informacién que se va a enviar es estatica, es decir, no depende | de datos extraidos de un almacenamiento externo, podra ser implementada por pagina o documento XHTML. 1.1.3 El Modelo En la arquitectura MVC Ia l6gica de negocio de la aplicacién, incluy el acceso a los datos y su manipulacién, esta encapsulada dentro del model Modelo Jo forman una serie de componentes de negocio independientes pomrolador y la Vista, permitiendo asi su reutilizaci6n y el desacoplamiento ete tre GUE $e envia anexado a la URL de la Peticis utiliza con esta finalidad: url?operacion=validar Otra opcién es utilizar la propia URL para realizar, en este caso, se utilizaria el p indicativo del tipo de accién. En es muestra las distintas partes en las que se p URL completa asociada a una peticién Same a de a apis Fig.4, artes de una URL i i i bre de dominio Por ejemplo, sien un servidor de nombre dé www libros.com tenemos desplegada una aplicacién llamada “biblioteca”, cuyo Controlador es un servlet que tiene como i pattern el valor “/control”, la URL asociada a la operacién validar podria ser: ue otra ‘operacion, por ejemplo registrar, tendria Come Mientras URL: www.libros.com/bibliotecalcom ‘ones provocarin la ejecucién del Tos a utilizar el método getPathinfo() del xy covet para determinar Ia operaciGn a realizar, i ion. Una vez que el Cont . amiento de Ia petici 1 ‘gt inentes, invocando para ello a los diferentes métodos expuesto, por el Modelo. Dependiendo de las acciones a realizar (por ejemplo, un alta de uy usuario en un sistema), el Modelo necesitardé manejar los datog enviados por el cliente en la peticién, datos que le serén proporcionados por el Controlador. De la misma manera, |. Resultados generados por el Modelo (por ejemplo, la informaciin resultante de una busqueda) seran entregados directamente aj iroUregistrar tici 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 mas que una clase que encapsula un conjunto de datos con métodos 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) { Generacién de respuestas. Los resultados devucl Modelo al Controlador son depositados por éste en wna vs peticién, sesién o aplicacién, segiin el al " im el alcance q continuacién, el Controlador invoca a la encargarse de generar la vista accederé a la variable de ambito d resultados y los utilizara para generar din XHTML que sera enviada al cliente PRACTICA 1.1. ENV{O Y VISUALIZACION DE MENSAJES Descripcin Para comprender la importancia de esta arquitectura, vamos a desarrollar una aplicacién Web siguiendo este patron MVC. La aplicacién con sencillo sistema de envio y visualizacién de mensajes a través de la Web, cuyas paginas se muestran en la figura 5. Cada mensaje estard for destinatario, un remitente y un texto. La pagina de inicio muestra dos enlaces con las opciones del usuario, la de visualizacién de mensajes le Hlevara a otra pagina (“mostrar-ht solicitard el nombre del destinatario cuyos mensajes quiere visualizar. En caso de tener mensajes asociados se le enviari a una pagina 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 opeién de envio de mensajes a less a tuna pagina en la que se le solicitaran los datos del mensaje que ie evi. devolviéndolo después a la pagina de inicio una vez que el mensaje ha s almacenado. 1") donde se le a Chay a Mensajes para ana | ee or oeel Fig.5. Paginas de la aplicacién Desarrollo Los mensajes manejados por la aplicacién serén almacenados en una tabla cuya estructura se indica en la figura 6. destinatario cadena de texto Fig.6. Tabla para el almacenamiento de mensaje Mensaje, que encapsulara los tres datos mostrarchtm y envio.jsp indicarin al servlet debe llevar a cabo en cada peticién ot patrin Modelo “controlador” en el que se i clase a ia que srabarMensaje(), encargado Iensaje, ¥ obtener Men: lamaremos S asociados al desti Los mensajes serin manipulados mediante tuna clase JavaBean llamada ‘880ciados a un determinado m. En cuanto a las vistas, serin implem L (inicio.htm y mostrar htm) y tres IS} zando el parimetro “operacion” entadas mediante cinco pig P (envio.jsp, ver jsp, nom insertado en la URL controlador el tipo de accién que se Listados aplicacién. A continuacién presentamos el cédigo de cada unc ‘Clase Mensaje Package javabeans; public class Mensaje { private String remite; private String destino; private String texto public Mensaje() (} //eonstructor que permite crear un objeto /{Mensaje a partir de los datos del misno public Mensaje (String remite this.remite-remite; this.destino=destino; this.texto=texto; } public void setRemite (String remite) { this.remite=remite; public return thi tie void setDestino(sering st ino) { ‘thie deatino=destino; } public string getDestino (){ return this.destinoy } pub’ this. texto=textor : ; f public string getTexto() { return this. texto; } : fs Clase Controlador Iie void setTexto(string texto) { package servlets; import javax.servlet.*; import javax.servlet http. *; import java.io.*; import java.util.*; import javabeans.*; import modelo. *; public class Controlador extends HttpServiet { public void service (HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { String op-request .getParameter ("operacion") ; //acceso a 1a pégina de envio de mensajes if (op.equals ("envio") ) : yi response. neuedtned? Neaiicenae bpchig $72. //grabaciOn de un mensaje - if(op. equals ("grabar")) { _ Operaciones oper-new Operacia “oper. pate mee mn is) eens Statement st; ResultSet rs; try{ a st=cn.createStatement (); etConnection() ; sering fen + trom mensajes where destinatario., taqi«nsele deatino+"'"7 cpexecurequery (taal) 7 aybist (+ je encontrado crea un objeto [ee st te oe tea Se while (re-next ()){ Mensaje m=new Men rasa nensajes=new ATE je (re.getString(*remitenter), re.getString ("destinatario"), ig re.getstring("texto")); ‘ mensajes .add (m) 7 : } cn.close() 7 } } catch (Exception e) {e-printStackTrace () ;} return (mensajes) ; } public void grabaMensaje (Mensaje m) { Connection cn; Statement st; s ResultSet rs; ; try{ a cnsgetConnection () ; , st-cn.createStatement () ; 4 String tsql; ; //a partir de los datos del mensaje construye //la cadena SQL para realizar su insercién tsql="Insert into mensajes values('"; tegl+=m.getDestino()+"', 1+ m.getRemite()+"','"+ m.getTexto()+"')"; st execute (tsql) ; n.close() ; : catch (Exception e) {e.printStackTrace () ;} } } inicio.htm shtml> envio.jsp envio captura de datos e controlador?opera’ «body center> chisGeneracion de mensajes eform method="post "> cept /2ebt/> ee cia ant mmannjersitos beim s

Snecoducca renitente +

Introduzca texto :
textarea names"texto">

submit" name="Submit" value="Enviar"> "reset" value="Reset"> ver,jsp <4@ page import="javabeans.*, java.util.*"%>
<—
EL FRAMEWORK STRUTS ee La arquitectura Modelo Vista Controlador constituye como hemos una excelente solucién a la hora de im; i visto plementar una apticacién Web en Java, aunque desde luego no esta exenta de inconvenientes Si observamos detenidamente el ejemplo de cédigo pre ad capitulo anterior, comprobaremos la existencia de dos puntos ‘débiles grandes aplicaciones podrian traducirse en un desarrollo excesivamente com dificilmente mantenible. Estos puntos débiles son: = Extension del Controlador. En aplicaciones en donde haya qu: gestionar varios tipos de peticiones, esto se traducira en un elevado mimero de lineas de cédigo en el servlet controlador, haciéndolo demasiado complejo y propenso a errores. Cédigo Java en paginas JSP. La presencia de cédigo Java en una pagina JSP, aunque proporciona una gran flexibilidad a la hora de generar las vistas, hace dificilmente mantenibles las paginas y obstaculiza la labor del diseftador de las mismas. por dividir el serviet cada uno de ellos de i tipo de utilidad que faci, : te en emplear algin tipo d a Ors opi mente y es aqui donde entra en juego Struts, lay tareas descrit eh FUNDAMENTOS DE STRUTS i framework 0 marco de trabajo desarrollado por ¢| Struts es ete un conjunto de utilidades cuyo objetivo es faci}; : nee seserolls de aplicaciones Web con tecnologia J2EE, siguiend ¢ optim pata MVC. ' de Struts en los desarrollos ofrece numerosos beneficios af 4 ee Jos que podriamos destacar: 2 programador, entre I + Control declarativo de peticiones. Con Struts el programador yy tiene que preocuparse por controlar desde Cédigo las distintas acciones a realizar en funcién del tipo de peticién que tlega ay Controlador. Este proceso es implementado por defecto por uno de Jos componentes que proporciona Struts, encargandose ‘inicam, el programador de definir en un archivo de configuracién XML Ig. mapeos entre tipos de peticién y acciones a ejecutar. Utilizacién de direcciones virtuales. A fin de evitar la inclusign directa dentro del cédigo de la aplicacién 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 asociacién entre una direccién virtual y su correspondiente URL o direccién real se realiza en un archivo de configuracién, de este modo cualquier cambio en la localizacién de un recurso no afectari al cédigo de la aplicacién. " Manipulacién de datos con JavaBean. Como hemos podido comprobar, los JavaBeans constituyen una pieza importante dentro de la arquitectura MVC al facilitar el transporte de datos entre las capas de la aplicacién. Struts proporciona un s6lido soporte para la manipulacion de datos mediante JavaBeans, encargandose automaticamente el framework de Ja instanciacién de los mismos, su rellenado con los datos procedentes del cliente y la recuperacion y almacenamiento de los objetos en las variables de ambito; be esto sin necesidad de que el programador tenga que escribir sola linea de cédigo, tee ae ; Esto no significa que los benef reflejados también en esta capa, ya implementar el Controlador ofrece Modelo, al tiempo que facilita una bu cios en la utilizacion de Struts no se vean que la manera en la que Struts. permite lun fuerte desacoplamiento entre lena cohesién entre ambos. 2.2 COMPONENTES DE STRUTS El marco de trabajo Struts esta constituido por los siguient componentes: : es elemento * Archivos de configuracién = EI! API de Struts = Librerias de acciones JSP 2.2.1 Archivos de configuracion Ademds del descriptor de despliegue web.xml definido por la especificacion J2EE, una aplicacién Struts requiere de otros archivos de configuracién adicionales, El més 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 aplicacién, por lo que cada una deberi tener su propio archivo struts-config.xml. La figura 7 ilustra la estructura tipo de este documento. Segiin vayamos avanzando en el estudio de los objetos Struts y la manera de utilizarlos en las aplicaciones, iremos conociendo los distintos elementos 0 tags que se utilizan en la construccién de un documento struts-config.xml. meno encoding UTES rs xan config PUBLIC. rrr) struts Configuration 1.2//EN" ‘ ie 1s forward globales--> ‘icién y objetos Action, ademas nto neem entre tipos de peticion y obj 5 0c bjetos forward locales es - schivos de recursos-—> ona yge-resources ../> Fig. 7. Estructura bésica de un documento struts-config.xmt ‘Ademis de struts-config.xml una aplicacién Struts puede incorporar otros archivos de configuracién, entre los mas 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 0 identificador asociado. Cada vez que se requiera hacer uso de alguna de estas cadenas desde la aplicacién, se hard utilizando la clave asociada a la misma. De esta manera si el texto tiene que set modificado el cambio se realizard en el archivo de texto, no en el cédigo. Entre las utilidades de este archivo estd la internacionalizacién de aplicaciones, pudiéndose definir tantos archivos de este tipo como idiomas se quiera mostrar en la aplicacién, o el almacenamiento d¢ mensajes de error personalizados. En capitulos posteriores s¢ estudiaré con detalle la utilizacion de este archivo. is a Sat in cservie™ ition. ActionServiet/servlet-class> “serviet-name>3 gervle-elas>Ork init-param z a meae> debug para nae para vale>2 owed tion restro ejemplo quedaria dela siguienteforma: = tae En Geeta 6" excociog ure. iets a etrike-contig vosizc "-//Rpache Softw: conf igurat so peed =f javartn apache ors/s Cada elemento incluye los siguientes aributos: = name. Identificador que asignard Struts a la instancia creada. «type. Nombre cualificado de la clase. 1 en el archivo de configuracion, el prosramador no necesitard incluir en la pagina JSP ninguna accidn de tipo useBean pare car ybtener la instancia, ni tam| acciones set/getProperty para accecsr a : i eee todas estas tareas de forma transparents propiedades; Struts se encargara de realizar ‘para el programador. Indicando esta informaci6 56_stRUTS_— IMPLEMENT? MODELO + directa ruts, su implementacion puede I os a! wo sere Sis hemos inelido este punto es eae veremos ahora ¢n el listado, 10s métodos de negocio implementados en la el, de. las clases ActionForm Pi tener un total desacoplamiento nie , podernos utilizar como pardmetros datos al a de las propiedades del bean de Sipe utlizadas por el metodo = Me pasar el objeto ActionFony completo. Otra opeion seria utilizar como parametro un segundo JavaBean “plat independiente del API Struts. ACION DEL 3.2.34 mente de S recibet anteriormente. Modelo y €! Co tipos basicos de vo quedé reflejado en el esquema de la figura 12, leva a cabo mediante una clase ita e aa elo se © fos métodos validar() y registrar) que se Tal y com entacion del Mod esta clase tiem ivamente de comprobar 1a existencia del usuario en la base d¢ le te de os en Ia misma. Ambos métodos actian sob muestra en fa figura 15. ro implemi GestionClient encargan respect datos y de registrar nue tabla “clientes” cuya estructura Se Fig. 18. Tabla de clientes Pet en Datos que proporci lientes, se incluye otra clase Me peer Hamada del Modelo. de esta clase sirven conexiones con ; de soporte para el resto de métodos ERENT En el siguiente listado se muestra el cd igo de ambas clases package modelo; import java.sql public clas: private public public Datos (String a //con catch (SQLExcepti e.printstac package modelo; import java.sql.*? import javabeans.*i Voumrtost neve =cn. createstatement OF equcequery (query) 7 pesultset * ara xe nestll? at.cierraconexi } catch! (exception e){ e.printstacktsace ()7 } finally return estado; 2 } public void registrar (RegistroForm xf) { [genera 1a instruccién 50% de inserci6n a partir //de 10s datos almacenados ©” e1 JavaBean Usuario fauring query = INSERT INTO clientes " muerygeraaieel” 4r£.getNombre () +" Fa: spewed ison) tere getUsuario ()+ a1, tmerf-getPassword ()+ (on exe. getBnadl 42.3.5 PROCESAMIENTO D) VALIDARACTION Y Reo ICIONES: 1 Tras el registro del servlet control oe definicion de las acciones, éstas se oo defi ncargar de Drocesar las peticiones quel ‘aber heredar a Action y sobreserbir eon dhe ncluyendo en él las instrucciones para pee AS CLASES TION ctionServie: mediante procesamier El formato del método execute() se mi ) Se muestra en la fii public ActionForward execute(Action Mapping mappi af ‘ActionForm form, ee ee request, ‘esponse response) { instrucciones para el tratamiento de la peticién Fig. 16. Método execute() de la cl Como podemos comprobar, el método debe devolver al Co ‘ActionServiet un objeto ActionForward con los datos de Ia vista que deb enviada al usuario. ‘Asi mismo, execute() recibe cuatro parémetras cuyo acontinuacién: ficado se describe mapping, Se trata de un objeto de la clase ActionMapping que encapsula las opciones de configuracion definidas para la accion sn el archivo struts-config.xml, entre ellas las diferent vistas a las que podra ser encaminado el ‘Seuario una vez completada Ia accién Normalmente este objeto se emplea para obtener al objeto ‘ActionForward que seré devuelto al Controlador, para lo que podrén uilizarse cualquiera de sus siguientes métodos corward( h it forward). Devuelve el ae fn or" String do a la vista cuya direeci6n Virtual gg aecificn cen el parametro- bis pevuelve un objeto ActionForwar eociado & cuya direccién se "espeifica en : atributo input del elemento asociado a la accién, i i ionForm creadc 1e e| objeto de Ja subclase Actior i 0 porel ee que almacena los datos del formulario cliente, Eq caso de que no se haya tiizado ningun ActionForm en 1a peticign, este pardmetro tendra el valor null. + request_y response, Contienst respectivamente los objetos HttpServietRequest ¥ Ht jletResponse proporcionados por e| contenedor Web @ ‘ActionServlet. Utilizando estos objetos e] trétodo execuie() podré tener acces) a las mismas opciones que se encuentran disponibles para ‘cualquier servlet HTTP. ‘Acontinuacién se muestra el codigo de la clase ValidarAction, utilizada en este programa de ejemplo para gestionar la accién de yalidacion de un usuario: package servietsi import javax.serviet -bttp.*7 import org.apache.struts.action.*7 import modelo.*; import javabeans.*7 public class ValidarAction extends action { public ActionForward execute (ActionMapping mapping, ActionForm form, i HttpServletRequest request, HttpServletResponse response) throws Exception { f , _ Hobtenenos 10s datos de conexi6n con la base [fae datos (driver y cadena de conexién) de ‘//ios parémetros de contexto definidos archivo we ie: 2 eee new Gest ionclient ValidacionForm vis (valiasenn //invoca al método saa [alinaiarle arta a ag if (ge.validar(vt)){ es ) else{ ret! mapping. findForvara Como podemos ver en este listado, el métod jastmucsi6n que contenga légica de negocio de so execute) no nlyeninguma veuario esti o no registrado en la aplicacién h aplicain Para saber sie implementado en la clase GestionClientes, Si el Senedtloes del método. validar imidar( devolverd el valor true), se itso se etionForward asociado a la vista cuya direccién "irate rad contrario el usuario sera aaa. En cuanto a la clase RegistrarAction, he aqui el cédigo de a misma: package servlets; dmport javax.serviet .http.* import org.apache.s' import modelo. *; import javabeans.*; public class RegistrarAction ext public ActionForward execute ( actionForm form, letReques! throws Exception { string driver-this.getserviet () getservietcontext () getInitParancte string cadenacon-this.getserviet getserviet context () getinitFarane GestionClientes 9: new Gestic = (RegistroForn) fo": cer (*cadenacon" clientes (driver, cade ge.registrar (rf) 7 sregistrado"); orward napping find anterior podemos observar como los Jernidos fuera del cOdigo de la aplicncign, accesibles para todos jg, como en la 5 en esta clase ; nO estan Ia base de datos esti arametros de Pin dentro del de conexién con Samet beat archivo web-xral: concretamente aa omponentes de Ia aplicacion xwschema-instance sun.com/xm1/ns/javaee /web-app_2_5-x8a"> tp: //java- sun xt-param> SE c .JdbeodbeDriver cparan-val 4 cade aram-name> e>jdbc:odbe: telefonia « Una vez implementadas las clases Action, es necesario registrarlas en el archivo struts-configxml dentro del elemento , utilizando un subelemento para la definicin de los parametros asociados a cada accion, ‘A través de estos parametros se le suministra a Struts toda la informacién que necesita conocer sobre cada accién, como el path asociado a la misma o el objeto ActionForm que deberd ser utilizado en la llamada a execute (). A continuacién se muestran las entradas a incluir en el archivo struts-config.xml para las acciones utilizadas en esta aplicacion de ejemplo: om: CAPITULO 3. DESARROLLO DE ELA APLICACHN Con Sra o Seguidamente, describiremos el signific to : ignificado de los atributos indicados en el element + path. Representa el serviet es path que debe de la peticién para que ‘ActlonServie ‘iv ee moles objeto Action, ¢s decir, el valor que debe aparecer ene cl canna path dela aplicacién y la extension do, Enel co de ls el caso de la entrada login jsp, el atributo act , iction de! fo oy ion del formulario debera gina de tomar el + name, Nomibre del objeto ActionForm en el que ActionSe volcaré Ios datos del formulario cliente desde el in a peticién, y que sera pasado como parimeto en la llamada al método execute”) de Action. El valor de este atributo debe corresponder con alguno de los ActionForm definidos en el apartado *s = type. Nombre cualificado de la subclase Action = _yalidate. Indica si se deben validar 0 no los datos del ActionForm. Si su valor es true, se invocara al método validate() del bean antes Ge hacer la llamada a execute(). El valor predeterminado es fase 1 objeto ActionForm. Su valor = scope. Ambito de utilizacién del siendo request el valor puede ser request, session 0 application, predeterminado. no se utiliza en ninguno de los Action de este m URL de la vista que debe ser enviada al clients dacién del bean (ejecucion del Mas adelante veremos un = input. Aunque ejemplo, indica | % en caso de que durante la vali método validate()) se genere algiin error. c ejemplo de utilizacién de este atributo. icon mento puede i i er Como vemos ademas en el listado anterior, cada el a icluir uno o varios elementos “. Estos elementos representan las posibles as? eee STRUTS. tras ucién de la de encaminat el usuari ean asociacion entre ta direceién virtual de Py 4 la vistas a Tas que S© PUN indicdndose en cad® 10 de ell Jement y la direccion fisica ‘Cada element rd> dispone de dos atributos: ico o virtual asociado a la vista. Este val fndForward) de ‘ActionMayaet ee) utili “1 método findForwe rear el objet0 * qtonrorward asociado & i vista a la quem que dirgi a usuario. ie path, Contiene lt URL relativa de la vista. RD GLOBALES cayalidar” y “registrar” que. pri ‘actionServiet puede teen peticiones por parte de cliente (“flogin” Y ‘“fpararegistro”) que simy 2 n dos deberian tener como deere en envio de a petcion 3 08 de les vist splcaci, sin que ea necesssio sr ningn tratamiento especial Por a Parte del Controlador. 3.2.3.6 OBJETOS FORWA! Kianis de lesatcicos ejecucitn de os objets Act anteriores, Para que esto sea posible se deberan definir unos elementos el atributo name contendra el path ath de la peticion asociada y path la URL relativa de la pagina destino. La definicién de los elementos globales se inclui elemento , que @ su vez estard thine, 20 aa del \-beans> y : «global -forwards> ="pararegi if : aes egistro" path="/registro.jsep"/> : feeteten pital pihpneae es sme jar en su atributo uri el identificador acces” odie indie oe Mentificadores de las librerias de acciones de § asociado a dicha libreria Los idefvos de liberia 0d, siendo sus valores ls indicus oe © 18 Prop indicados en la tabla de la figura 17 libreria identificador ie http://struts. apache. Flees logic http struts. apache oraitags-k aaa reset http://struts apache Reina Fig. 17. Identificadores de las librerias de Strut Seguidamente vamos a analizar cada una de las c utilizadas en esta aplicacién. oes TSE Jogin.jsp Es la pagina de yalidacién de usuarios. Los datos son recogides por formulario XHTML y enviados a ActionServlet que los encapsularé en ob ValidarForm, El siguiente listado corresponde con el cddigo de esa pagina = ares http: //struts-apache.org, <{DOCTYPE HIML PUBLIC "-//W3C//DTD # Transitional//EN" “http: //www.w3.org/TR/html4/Loose .dta">
ghisFormulario de autenticacion< Greml {form action=“ /validar® metho: enysuario" /> pehtml text property" ‘ ae edopasaword pasewor fede o property=rDAasNOxan/ alesis eedoeht ml
Usuario:
Spemt mubat Broperey-"S
1. form>
aes nk forward="pararegistro” >Registrese Como podemos ver, la pagina hace uso de la libreria tags-html, Esta incluye acciones que se emplean para la construccién de interfaces grificas de ins pasadas en formolarios XHTML, ademés de otros elementos dinamicos aaaar no enlaces o imégenes. Aunque podrian utilizarse etiquetas XHTML tetandares para la implementacion de los formularios dentro de una pagina JSP, el empleo de estas acciones facilita enormemente la labor del desarrollador, puesto ue, ademas de ser més intuitivos sus nombres y atributos que los de las etiquetas SHTML equivalentes, los tags html de Struts encapsulan parte de la funcionalidad encargada de la manipulacién de los form beans y su rellenado con los datos procedentes del formulario cliente. i Veamos a continuacion el funcionamiento y analicemos los atributos mas importantes de las principales acciones incluidas en la libreria tags-html: * . Genera la correspondiente etiqueta con las caracteristicas de localizacién propias del cliente. Jae rm>. Equivale ala etiqueta
y como en el c2s0 de spies irae a asa Aa pitied coh, 7 atributo method contiene el método de envio utilizado por 1a peticion RA- exams _cartruo -APITULO 3. DESARROLLO De un, PLICAGION CON STRUTS, ODE UNA, x © siendo su valor por defe ee fecto “POS' el path asociado al objeto Acten oo Sumo 8 ac peticién, segin la informa: Cnseneioagene en nico puede apreciar en el cé & struts-config.xml igo de las paginas anteriores, la afiadiendo a la izquierda del valor Original el gi context aplicacion y a su derechs Pe @ la extension do En el caso de login jsp, el cas ,¥ Suponiendo iicricel Secaivheigccne cay el directorio virtual de la sera transformada en: Registrese< que al ser solicitada la pagina sera transformado en: Registrese = action. Nombre légico del objeto Action que tr: generada desde este enlace. atari Ia peticién = href. URL a la que sera enviado el usuario al pulsar el enlace. = linkName. Nombre de la marca local existente en la propia pagina donde sera enviado el usuario al pulsar el enlace. e Seguin se desprende de su significado un elemento debe contener uno y sélo uno de los atributos anteriores. Otros elementos de esta libreria como o seran estudiados en el proximo capitulo. registro.jsp Se trata de la pagina de registro de nuevos usuarios. Los datos. son recogidos por un formulario XHTML y enviados a ActionServiet que los encapsulara en el objeto RegistroForm. El codigo de esta pagina se muestra en el siguiente listado: *text /ntml"*> ‘UTF-8"%> ruts apache .org/tage~ hemi" property="email"/>

rare bienvenida jsp Es la pagina que se muestra el c6digo de la misma: al usuario una vez que se ha vaidade idado, he aqui <%@ taglib Bienvenido En esta pagina se hace uso también de una de las acciones de la libreria tags-bean, coneretamente de . En el capitulo 5 se analizara el funcionamiento de ésta y del resto de las acciones que componen la libreria, de momento comentar que permite mostrar en Ja pagina los valores almacenados en las propiedades de un bean. nn sreuts_ po DE LLAMADAS DE USUARIOS Con tos. conocimien'’h que ya, tenemos sobre Struts estam ae primers’ practioa COR Strut, ae ello plementar nue ' de ejemplo qe hemos ido desarrollando a lo 1 fargo dey pRACTICA 3.1. LISTA! condiciones de im partremos del ejeroil capitulo. Deseripcin Se trata de desarrollar el listado de las Iamadas realiza‘ Sn operador de selefonia. Tn van apiccion que permit = [eS UStaHlO3 ma cualquiera de los teléfon0s Co ae mente el usuario accederd a una pagini 08 con, de deberd validarse ¥, 0 CAS! de que se trate de un usuario ane de login donde ona pigins doe deters OE sn una lista desplegable el ST ee sot aadas que visions ual se le mostraré una Sea 4 paging ton tos datos de las lamadas realizadas. La figura 18 mues co 7 =e ti pizinas de la aplicacion ra el aspecto de las copsionesisP losing capiruto. . DESARROLLO DE Una, APUCACION CON STRUTS iis de ValidarActi ; jentacién, adem action y RegistrarAci § Mp accion a 1a que lamaremos Listadgar Ge Se encase tadoA cti - licita el listado de Hamad; i A eat’ de gestionar la jon que SO) A acs & Partit del teléfong Seleccionado, Asi i yer el obj ccna lo a ta vista, ta devolvd.jsp Sino opciones sp cual bit Por oto lado, serd necesario cn mos OpcionesForm, que contendra Manvario. Crearemos ademas un JavaBean “planes amado Llamada’ of ustiile 1os datos de las lamadas telefénicas Para facilitar su tratamiento encaPS sp, el cual Se apoyard a su ver en oun spl cae ta los datos de las tarifas. Tami ea almacenar la lista de teléfo yu, UM MWeVO ActionForm, : al que cl niimero de teléfono seleccion: ado por jean que desde la © JavaBean llamado Tarifa que én modificaremos ValidacionForm a fin NOs asociada al usuario validado. represe! de que ito al modelo, se crearin dos nuevas clases Mamadas En cuant ‘Telefonos y GestionLlamadas que proporcionaran toda la légica necesaria fee etes telaformnaci6n’ relativa.a los nimeros de telefono usuario y las ara 0 ta inf Tlamadas realizadas. fn lo figura 19 tenemos un esquema camplelo dela bate de datos ae que utilizaremos en esti aplicacién, indicandose las tablas que la es exrnpce definiios en cada una de clas. compo! telefonos ‘Campo | Tipo clientes tlamadas Campo [Tne | Jidttamada | numérico ih ie . |_sfrcetino [nani tarifas destino _| numérico password | texto telefono | numérico =e duracion | numérico isis | amo | datos de la aplicacién Fig. 19. Base de rate edara el archivo de ih 0 En primer lugar, mostraremos com? 4 i assole ide Ia aplicacion, & * | que podemos ver 10s contp forman: eqemi versions" -0" encoding="UTF-8" 7° _rpocryes struts-coness PUBLIC * morewres founasiacaee //spache, (27 snag configuration 1.2//EN" enetp://Jakarts config 1. 2-atd"? a apache org/atrute/atds/strutas estruts-config> ‘eform-bean name: nopcionesForm" types "javabeans .opeionesForm"/> wpegistroForm" type «global-forwards> forward name="login” path="/login.jsp"/> cforvard neme=*toregistro™ ‘patha"/zedt ="/registro.jsp" a action name="ValidacionForm" path="/validar” er type="servlets.ValidarAction"> pe name="bienvenida" path="/opciones.jsp"/: eae cacti m= oe ae "/xegistro.jsp" name="RegistroForm" /registrar" scope="request" eforwar Arges ‘oRAMA CAPITULO. DesARROL 9 REWNA AMLICACIN Seguidamente mostramos ¢| |j yicacion y de aquellos que han sido Componentes de | la ap) tes: adicando en este dltimo caso los cambi aos FeSpecto al indi 0S realizados en fonds sa erro Stalizado, mo ValidacionForm package javabeans; jmport Org-apache.struts.action.« import java.util.+; og public class Validacion¥orm extends A ti //almacena los credencial : private String usuario es del usuar private String password //almacena el mensaje asociado a //de 1a validacion private String mensaje; 1 resul private Arrayhist teletonos; public String getUsuario() { return usuario; } public void setUsuario(string norbre) { this.usuario = nombre; } public String getPassword() { return password; } public void setPassword(str: this.password = password: ing password) { } public void setMensaje(stri this.mensaje-mensaje7 ng mensaie) { a public String getMensa: return mensaje? ie (4 sans package ieee vaction-*7 import oF: public class OPS: ttionForm { //almacena el nimero ¢ numero7 umero() { jonesForm extends Ac| de teléfono private int public int get! return numero; . public void setNumero (int wee numero = } } ValidarAction - package servlets; inport javax.serviet EtD.*; import org.apache.struts.action.*; import modelo. *; import javabeans.*; ee validarAction extends Action { SCE aEorta re execute (ActionMapping mapping, ActionForm form, tConte, 3 text () GestionClientes ge. new GestionCiiente AEGeWasaEe (vey GestionTelefonos gt. Rew Gest Hprecpera 105 nine ValidacionForm yf. felefonos (dri ver cadenaCon (fos almacena ene} ten /feara que pv //a la vista "bie; VE.aetTelefonos( St-GetTelefonos (vt get eassword: Password(})) ; xeturn mapping, fi } ndPorward (*bienve: } ListadoAction package servlets; Dot import org-apache. struts import javax.serviet. import org.apache .struts.actions.*; import javabeans.*; import modelo.*; import java.util.*; public class ListadoAction extends Ac public ActionForward execute (ActionMape ActionForm form, quest. reques! HttpServlet® pttpServletResponse Tespo throws Exception { of=(OpeionesForm) form; madas (request al opeionesForm GestionLlamadas gi-getGestionhia //recupera el listade de lamadas asociadas request BeeRCCEaD : reques ransaaaTezecono (of -SecHUmasiy Tag gi.getTodae cree return Spine. £AndrOEMA | stado") ; fi } ,cute jyubeodo de BPOY? * exe private gestionbiamadas getcestionblamadas ‘ueepservietRequest request) { eserviet ()- ariver=this-3 1 () .getznitParameter ("drivers i contex nis.getserviet () - qnitParameter ( "cade: ae (driver, cadenaCon) ; i string gerserviet' cadenacon=t context () get: eionbiamadas string getserviet return new Ges } LlamadaBean package javabeans; import java.io.*7 public class LlamadaBean 3 private int telefono; private int destino; private int duracion; private String tarifa; private double coste; private String fecha; re blamadaBean() { public int getTelefono() { mplements Serializable{ cartrer rams LO 3. DESARROLLG DEUNA APLCACAG public int getDuracion() “cover return duracion, ) public void setDuracion(: this.duracion = durac } public String gettarita() return tarif } Pee aretha aa td this.tarifa = tarifa, eee public double getcoste() { return coste; ) public void setcoste (double cost this.coste = coste; " } public String getFecha() { return fecha; } public void setFecha (String fecha! this.fecha = fecha; } Tarifa package javabeans; public class Tarifa { private int idtipotarifa; private String nombretarifa; public int getIdtipotarifa() { veturn idtipotarifa; } public void setIdtipotarifa(int ict this.idtipotarifa = idtipotarifa: potarifa) { } public String getNombre yeturn nombretarifa arifal) { carife (string nombretarifa) { ‘ponbretaxs fay jonnlamadas (StxiPd river, String cadenacon) { patos (driver, © public Gest: at=new adenacon) i ; Hobti jon determin public Array! end todas 126 Liamadas asociadas a ado teléfono jet get TodasblamadasTelefono( int telefono) { Cainer Ce aoe n liamadas where "; suerpartipict eno MtSLETON?? return getblamadas (query, telefono) ; } private ArrayList getLlamadas ( string sql, int telefono) { prraylist Llamadas= new Arraybist () 7 try{ connection en=dt .getConexion() ‘Statement st -cn.createStatement (); a llamada lamada.. se catch (Exception e){ -printstack finally{ return 1 //recupera el //eavifas a parti priva' String tarif try{ Connection ring quer query +="wher Statement st ResultSet rs //si existe un: //devolverd su £ (xs.next ()) tari } at .cierraConexion(cn) } catch (Exception e) e.printStackTrace() ; } finally{ return tarifa; GestionTelefon0s package model? import import JaV4 public class patos ati public gastdonTereronee (SEE ing driver, String cad f dt=new patos (driver, cadenacen) : 4 coleccién con todor 208 teléfonos 1 usuario //aevuelve un nnteger> getTererones (String Pasi onay /fasociados 3- public Arraylist< rernteger> mumeros= arraybis new arraybist() try{ connection cnedt .getConexion() 7 paisa query ~ seeest TALEND: 5g telefonos where password ='"; query+=password+"'"7 : statement st =cn.createStatement () Fi ResultSet rs = st .executeQuery (query) 7 while (rs next (1) { nuneros.add (rs .get Int ("telefon i } dt.cierraconexion (en) ; catch (Exception e) { Capitulo 4 ANALISIS DEL APLDE STRUTS Después de ver en accién di lurante el capi componentes de Struts, a lo largo de los oe, anterior Setalle estos components a fin de poder explotara San os : lo todas a los diferentes famos a analizar en sus posibilidades En este capitulo profundizaremos en el estudio del API d Io que se refiere a los componentes del Contoladar como alos eBoy tegen lege 10 a los JavaBeans de tipo 4,1 PROCESAMIENTO DE UNA PETICION IN : CLASES ACTIONSERVLET Y REOUESIPROCESSOR Como ya quedé indicado durante el aniliss del capitulo anterior ActionServlet representa el punto de entrada a la aplcacin tru, de tal manera que todas las peticiones HTTP que llegan desde la capa cliente ala aplcacion son dirigidas a este servlet. Una vez recibida la peticién, ActionServlet delega el anilisis y procesamiento de la misma en un objeto RequestProcessor. Este objeto es el al tratamiento de la peticién encargado de realizar todas la operaciones relati descritas en el capitulo 2, como son el andlisis de la URL de la peticion, instanciacion y rellenado del ActionForm, determinacién del objeto Action 2 gjecutar e invocacién a su método execute(), andlisis del objeto ActionForward retornado y transferencia de la peticién a la vista correspondiente. a g4_ STRUTS a OPA jizada de forma independiente por j, los por caliipace struts action RequestProcessoe Estos métodos tienen Tementacion por defect dU; normalmente, sucle se, Eetotada en 1a mayoria de 10s ementare No obstante el hecho de que cada tae, do diferente permite al programador personalizar de mane, Findo subclases de RequestProcessor en a 08, sea tratada por un mete re i jalizada est 3, cl individu: inte aquellos métodos cuyo comportamient 0 sobrescribiremos jo nos inte a de estas tareas eS Teal Cada uni ‘oporcion: distintos métodos Pr ‘una imp! tas operaciones que vinicament srese cambiar. predeterminad .; métodos de la clase RequestProcesso r, .s de los principales n ejecutados: He aqui alguno: ‘el orden en que SO! Los analizaremos segun path). Analiza Ia URL de la peticién y obtiene el path que nar la accién a ejecutar. rocess} ara determ! ser utilizado pé ica si SE continuara 0 no procesando |a ués de que este método se haya ejecutado. En sy n por defecto processPreprocess() unicamente tiene rel valor frue para que la peticion siga Ilo que si el programador desea introducir n del cual el procesamiento de la la sobrescritura de este método sPreprocess()- Indi proces peticién desp' implementaci6 como funcién devolve provesdndose, ¢s por el flgin tipo de control en funcio peticién pueda ser cancelado, constituye una buena opci6n. 0. A partir del path obtenido durante la ejecucién Ja implementacién por defecto de este método se | elemento , tal y como se continuacién: © on MiRequestProcessors/, public ActonForward metodot(.).) =metodo2 direecion.do? | Patametro=metodo: ae ca parametro=metodo3 Aisin as ye Fig.21. Equivalencia entre valores de pardmetro y método 7 ion” bre de parimetro las eyar ejemplo, si elegimos “operacion’ pane ee ain URL ocaran la ejecucion ee n() re erlamdh respectivamente, defini ne oe 90 STRUTS sstioncarrito.do?operacion= insertarliem, irervidor/miaplicacton/ae ntip://mis roncarrito.do?operacion=eliminarltem, idor/miaplicacion/gest arp: imiser¥ iaplicacion/gestions Intp:/imiservidor/! ccarrito.do?operacion=obtenerltems i i del método a ejecutar no ti El parimetro que determing el nombre jecutar no tiene que ecesariamente insertado en in URL, podria emplearse cualquier meee formulario enviado en Ia peticion. " si nombre elegido para él pardmetro deberé quedar capecificsdsen in del elemento de struts-config.xml a través de su asian En el ejemplo que ‘estamos analizando la configuracién de a gestion de peticiones relativas al carrito de la compra q este itinuacion: configuracis parameter clemento para como se indica a con < En 1a definicién de pardmetros name Y scope por ser irrelevs Fin embargo en un caso real deberian ser es algiin objeto ActionForm. OPCIONES PARA LISTADO DE LLAMADAS DEL este elemento de ejemplo hemos omitido | antes para el tema que estamos gate pecificados si la aplicacién hace uso de PRACTICA 4.1. USUARIO Descripeion __ Se rata de realizar una version ampliad de Ia licacién desarro! prictica Ee a crim amen En a move cc A ie : de opciones de cara a visualizar el listado de Hamadas de un es en la posi lidad de elegir el tipo de Hamadas Sa, ida et pr nal! nist EO Te, ee ath eae Mpiatir Opciones para el ttado ac = ey | certs ren Fig. 22. Aspecto dela pigina de op opciones Funcionamiento —En vez de crear una clase Action por cada oj tinica clase DispatchAction con tres métodos, uno para cadz tro llamado “operacion” generado pot \ Se en Mean 3 los bot Ajeervidor el nombre del método a ejecutar para cada eats i cviem pein a gestionar,utlizaremos Tanto el niimero de teléfono, como la opcién elegida, asi como los dat adicionales asociados a cada una, serén encapsulados en el bean OpeionesForm. 2 Por otro lado, sera necesario implementar un nuevo bean, llamado Tarif we encapsule los datos asociados a las taita, Este JavaBean seri uilizdo = generar la lista de tarifas, cuyos datos serin mostrados en la lista desplegable asociada al tipo de Hamada. “siguientes listados corresponden a los _ nuevos elementos dos en esta versin de la aplicacién, asi como a aquellos que han sido jindicando en este caso en fondo sombreado los cambios introducidos. 92_ STRUTS roundation//DTD Struts n-/[apact ‘contigurarsem tease jakarta apache “org/strute/dtds/struts- : gankig 12+ deo" ne software entep://: estruts-contig> nopeionesForm" type="Javabeans -opcionesForm" /> npegistroForm” eypextjavabeans Regist rororm’ ‘Aes wyalidacionForm" eform-bean name> wjavabeans-ValidacionForm"/> type=
path="/registro.jsp"/> eaction-mappings> action input="/" name="ValidacionForm" path="/validar" scope="request" serviets.Validaxaction"> forward nane="bienvenida" path="/opciones -jsp"/ “forward name="error" path="/login.jsp"/> b
“action input="/registro.jsp" name-"RegistroForm" path-"/registrax" scope="request" type="servlets.Registraraction"> package Javabeans; public class Tarita ( private int idtipotaries, private String nombretarita, public int getidtipotarita,, return idtipotaria, } public void settatipotarita ins this.idtipotarifa - an { ide: Spotaritay { idtipotaris, ; a; public String getNonbretarisa() return nombretarifa, { } public void setNonbretarita (string : nombretarita) { this.nombretarita = nombretarifa. | } } OpcionesForm package javabeans; import javax.servlet.http.+; import org.apache.struts.action.+; " public class OpcionesForm extends ActionForn { private int numero; tte String operacion; public int getNumero() { return numero; GestionTelefonos package modelo; import java.sql.*7 import java.util.* import javabeans . Tarifa; public class GestionTelefonos { Datos dt; fonos (String driver, public GestionTelef< ; est ae si public ArrayList < Array! try{ Connection cnedt Tarifa tf=nul //instrucci //los tipos de String query ~ Statement s ResultSet rs while (rs next ()) { tf=new Tarifa() tf-setIdti tarifa (rs.ge t£.setNombret: wifa rs.getst: tarifas.add(té) ig (*nombretarifa*) } at .cierraConexion (cn) ; } catch(Exception e) { e.printStackTrace() ; } finally( return tarifas; GestionLiam™ jas package modelo? import java-#a dmport java-vedde "7 import jevansens:"! import java-text public clase Gestion! patos ati public Gestionl! dtenew Datos (ard } public arraybist getTodastlanadasTel| gnt telefono) { ee agelect * from liamadas where " 1 ntelefono="+telefonoy ‘amadas (query, telefono) 7 lag llamadas, comin para los dos ex, String cadenacon) { get) Mamada-setcosta (rs Setboubiey Mamada.setrecna (ry. : Tiagittecne ERs easy TN Eines, } Gt -clerraconexion(en) ; } catch (Exception ¢) { e-printStacktrace(), } finally{ return llamadas; Rew AtrayList +, javabeans.*" *> _//etxucs.apache .org/tags-html" <46p: ntext/html"$> cbr/> "Mostrar listado"/, « 4,2.2 Clase LookupDispatchAction ubclase de DispatchAction que, al igual que ésta, tiene ticiones en una misma clase mediante la definicién para cada accion, utilizandose el valor de un determinar el método que se tiene que Se trata de una si como misién gestionar varias pet de un método personalizado parimetro enviado con cada peticién para ejecutar. A diferencia de DispatchAction, donde el valor del parametro contiene directamente el nombre del método asociado a Ia accién, LookupDispatchAction utiliza el valor de este parémetro 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 método que tiene que ejecutar, para ello tendr que acceder a una tabla de tipo Map donde se encentran almacenados los nombres de los métodos del objeto con ‘sus correspondientes claves asociadas (figura 23). La implementacién por defecto del método execute() existente en Looe iae a inyoca al método getKeyMethodMap() de la propia clase Se mapa de métodos con sus correspondientes claves. Es responsabilidad del programador sobrescribir este método e incluir en él las ‘nstrucciones apropiadas para generar esta coleccién. CAPT « nd ApplicatonRerource prope AROESTRUTS. ep Vie Nats ia parametro=valor! direccion do? : parametro=valor? ible ActonForward metdett-) public ActionForward metede3{_.)(.) Fig. 23. Tratamiento de peticiones con LookUpDispatchAction Por ejemplo, volvamos al caso de Ia clas DEP. 5 sopcceacee que Goceu ace bn agro valores del pardmetro operacién: “opcion!”, “opcion2” y “opcion3” a los aaa insertarltem(), eliminarltem() y obtenerltems(), respectivamente. Lo primero Ke debemos hacer es asignar una clave a cada uno de los valores posibles del pardmetro, por ejemplo: oper.insertar=opcion! oper.eliminar=opcion2 oper.recuperar=opcion3 se incluiran dentro del archivo de recursos Las lineas anteriores ‘Web. - ApplicationResource.properties de la aplicacion “A-continuacién debemos implementar el método a os Hi ere una tabla CarritoAction, de manera que gens s finidas anterormete a de la clase utilizando como claves las archivo de recursos: Esta seri Ia nueva implementacion de Ig GestionCarritoAction: GestionCarritoAction getKeyMethodMapOt public class extends LookupDispatchActionf public Map Udefinicion de mapa de métodos Map mp=new HashMap0; mp,put(“opcion.insertar", "insertarltem"); mp.pus("opcion-eliminar”, "eliminarltem"); mp.put("opcion. recuperar", "obtenerItems"); return MP; ‘public ActionForward insertarltem(. AG método que lleva a cabo la insercion de un elemento Wen el carrito j public ActionForward eliminarltem(...)£ /método que lleva a cabo la eliminacion de un elemento Loo ica 4.1, import: import import import import _ import : Permite ng gating necesidad de alterar el odin Ge uedan ser Como ejemplo de utilizacion de jstado de Mlamadas de Ia aplicacién de ta ye cupDispatchAction. Lo primero sera afadir lag soy asociado al objeto Lookupp arputo parameter el nombre del parém at onResource.propertice ‘Que hacer 'SPatchAction, ~ ON, €n el regi. et on tion Fad que eee meat Wiado en la peticigg, we EM el esta clase, vam, clavesal archivo ApplicationResource.propertieg. “SMES cadenas con say opeion.todas=todas opcion.portipo=tipo opcion.porfecha=fecha Practicamente igual a la de la afiadiendo simplemente la implementacién del método javax.servlet http.*; org.apache.struts.action.+; org.apache.struts.actions.*; javabeans.*; modelo.*; java.util.*; Mra rodas (nctsonMapPang wappine, 8 onForm £0X™, quest request, am sponse response) public ActionFo) acti eepservietRe perpservietRe! jon opcionesForm of= (opcionesForm) form; Gestionblamadas gi-getGeationblamadas (request) ; a pivot Acer babe a Eemac aay si .getTodasZlanadaeterefone (90 ges zsh ? return sapping .£indrorward( "1istadon) ; throws Except: public ActionForward portipo(actionMapping mapping, ‘actionForm form, petpservietRequest request, petpservietResponse response) throws Exception { opeionesForm of =(opcionesFozn) form; Gentiontlenadae gi=getcestionblanadas i Saueee)iy request satattribute(7iianadasty gi .getLlanadasTelefonoPorTipoTarifa( of .getNumero() ,of .getTipo())); return mapping. find¥orward("1istado"); } public ActionForward porfecha (ActionMapping mapping, ActionForm form, 4 uttpServletRequest request, ‘HttpServletResponse response) _ OpcionesForm « -=(OpeionesFor) £ siti ‘ pig ete oes on mse SE)? "Llamadas" ie iced, getServietcontext () return new Gestion) ) ae e, mn ; 8decacony Ne £n cuanto a la pagina opciones j 7 serie operaciones (para que no eee : ig métodos), segun 10 indicado.en el archiyg Applian con log gal det etepage contentType="text /ntatay OUrce properties: JSP Page y
Opciones para el listado de Manadas Seleccione nimero de teléfono:

almacenado en una variable de peticién--> <*ArrayList lista=((ValidacionForm) request .getAttribute ("ValidacionForn")) .getTelefonos (); for(int i-0;iclista.size() ;i++){%> "> ctelista get (i) tostring() #> elect> pr/>
< eposeleccion , eat ee sroperty=operacion" values"Eodaany, e/td>etd glign="left">Todas < uta alignerieft*>seleccione Tipo chemi :eelect property="tipo"> ej--Recupera el Arraybist de taritas jimacenada en una variable de peticign._ caarrayList tarifas=(( a arraybist) request. getattribute ("tarifasn)), for(int is0;ictarifas.size() ;i++) int id=(tarifas.get (1)). getIdtipotarifa(); String tré=(tarifas.get (i). getNombretarifa() ;%> "> . Pe SAOESTIOTS iy
¢/heml shtml> 42.3 Clase MappingDispatch Action ‘ Se trata también de una subclase ge Dig 5 i PatchAction que, al j ores, permite definir en ta misma clase un gat al igual que tas lee ateretites, Bio de métodos para la geen de peticiones En este cAS0 no se utiliza ningin parim, jodo a ejecutar, sino que cada peticion utilizara un Path diferente Beeesericoilolque obligara 2 defn en el struts-config xml Metion> asociados a la misma subclane ge MappingDispatchacion ae distintas deba gestionar el objeto. Utili peti ee tilizando el atributo parameter del nto se indicard para cada peticin elnombre a Método que se debe ejeentar, consiguiendo asi el desacoplamiento ene el san y-el nombre del ‘método (figura 24). HO que permita determinar a struts-config.xm! /direccioni™ ymeter="metodol"/> ction path=" /dircccion2" ieeasaie metodo?” /> Reeuperaciss del nombre de método Llamads at @\ rive 110_ STR para entender el funcionamicst® volvamos al ejemplo del carr entemwtilizado com Ins clases anter Ore Supongamos que t ree enlaces en [a pagina cliente ave Tanzan las peticiones para la realizaign tres operaciones descritas sobre el carrito: realizacion dey Anadir elemento * eq href="eliminar.do "> Eliminar elemento Recuperar contenido tas tres peticiones provoquen la ejecucién del n deberiamos registrar los siguientes elementos en e GestionCarritoActio archivo struts-config.xml: path="agregar" type="misclases.GestionCarritoact: ninsertaritem"/> tony nmisclases.GestionCarritoacti, on «action parameter= action path="eliminar” type= paraneter="eliminaritem"/> action path="recuperar” type="misclases .GestionCarritoaction" parameter="obtenerItems"/> Los valores indicados en el atributo parameter de cada elem 5 anterior epresetn fos nombres de los métodos de la clase Gain cee tsociados a cada accidn. La estructura de esta clase seré indi siguiente listado: ee ‘public class GestionCarritoAction extends MappingDispatchAction{ public ActionForward insertarltem(...){ “método que lleva a cabo la insercion de un elemento a. SSSA EN } public ActionForward obtener " Mmétodo que leva a cabo a Medel contenido completo del cern } ACTICA 42. INFORMACION TELEFONICA pRAt cripcion ’ Sea a s Dest ite practica consistira en la implementacion de una variante de la eae Ocasin, una vez validade ct yicacion Nee Scere tuna pagina de opciones de informacién que le permitiran usuario. 8° ie We iicidimos recisteloe vas nombre, a Sonocer el consumo. isualizar el historico de llamadas. La figura 25 iustra las paginas de acumulado © ain incluir las de validacion y registro. Ja aplicaci’ y sumer op 112_STRU: ene Funcionamiento ada a cabo por la clase Opci jon de las opciones sera Ilevada @ c ital en cece ina subclase de MappingDispatchAction con tres ment serciados a cada uno de Tos enlaces de Ja pagina opciones,jsp, asociacién que coy" hemos indicado se realizara en cada elemento de struts-config.xmi, —"” Por otro lado, se ha modificado el pee ze objeto Validaciong, ree era sera posible tener acceso al lop,” sando de request a session. De esta man’ i < oa je desde la pagina factura.jsp 4 fin de personalizar el mensaje mostradg usuario. cédigo de los nuevos elementos Listado traremos el 3 asi como las modificaciones realizadas en los ya Seguidamente most desarrollados en esta préctica, creados. struts-config.xml "1.0" encoding= UTE-8" ?> siempre pueda reco es durante toag GestionLlamadas package modelo; import java.sql.*; import java.util.*; import javabeans. import java.text.*; finally{ return 11, E } Suadas; } public double getPactura, String query = "ge1¢, String p; ee query+="telefono in Namadas vhere queryt=" where passwora o.+,. double total=0.0, : try{ Connection ons Statement st Resultset rs St -getConexion() , eR. createstatement = st -executeguery (que, if(rs-next ()) { Ty (query) totalars.getDouble(*totainy, dt .cierraConexion(cn) } Gatch (Exception e¢) { © .printstackTrace() } finally{ return total; } private String ge! String tarifa=null; try{ Connection «1 dt .getConexi String query = “select nonbretarifa from tar query +="where idtipotarif Statement st =cn.createst ment () j ResultSet rs = st.executeQuery (su if (rs.next ()) { tarifa=rs.getString(" ombretarifa") } dt .cierraConexion (cn) ; } catch (Exception e) { ) OpcionesAction package servlets; import javax-servier-httP.*/ apache.struts-action.*; import org- ctions.*; import org.apache- struts. import javabeans.*; import modelo. *. import java.util. public class OpcionesAction extends MappingDispatchaction ( public ActionForward factura( e ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { teen seme getSession Oe i MAL CAPITULO Andis, one * SDEL AMIDE Stats /asociados a1 us, : uario return mapping. finars reward (*y ; (*vistanumerogs) , public ActionForward detalies (Acts, nay ActionForm form enc, BtepServietRequest. reque HttpServietResponse req throws Exception { aor HeepSeasion sesion-request et segs: ValidacionForm vé=(valigacio, GerAttribute (+va1 i, Gestionblamadas gl-getce stionLLanadas (request request .setAttribute("l1anadas oe Gi. getLlamadas (vf .getPassvor xeturn mapping. find?orvard(*vistadetalles" } private GestionLlamadas getGestiontlanadas| HttpServletRequest request) { String driver-this.getserviet () getServletContext () .get: nitParaneter ("ériver’ String cadenaCon-this.getserviet () getServletContext () .getInitParaneter (*cadenaCon" xeturn new Gestionblamadas (driver, cadenaCon) ; } opciones.jsp __ cé@page content Type="text /ntml"+> <#epage pageEncoding="UTF-8"$> ee prefix Tm 4.02 ce "-//w3c//D™D - eect: HTML PUBL: ‘transitional/ /2N’ bi .dta"> http: //wew.w3 .org/TR/html4/1o0se etext fhm + content=" »content-TyPe —— emeta neep-equiv= cotyle? Re gine ecenter? ‘chivopesones Pax# bea cedvehtel:Link page="/mumeros. don Mostrar sus nGmeros s usuario ctdscheml:1ink page="/facturacion.dors Facturacién total del usuario a Detalles de llamadas Re : smeta http-equives, Content tye charsetaury gs” ttenterten, asp Pagec/titie, Tote, </head> <body> <center> <br/><br/> Sbr/>ebr/, lista. Seasicn Bites retraricichrenl on. setTeletonos() , iiligta.size() 144) (45 Ed) .tostring() ts for(int iso <¥-lista.ge <br/> <t)t> </h2> </center> </body> </ntml> detalles.jsp <t@page contentType="text/html"t> <¥@page pageEncoding="UTF-2"%> <%@ page import="java.util.+,javabeans.** ts - "text/html; <meta http-equiv="Content-Type" content="text/) charset =UTF-8"> aye width="608"> evable borders “ethoTeléfono del suario</td> Tprenéfono aestino</ eho ethopuracion (segundos) </th> ethoTarifa</th> B ethocoste</th> echoPechac/th> cefor (int in07dellamadas size() ist) { plamadabean jiamada=ilamadas.get (i) ;%> <tr> ctdyct=1lanada.getTelefono() #></td evant Te cpdsct=Llamada .getDuracion () ¥></td: ctd><t=Llamada .getTarifa () ¥></td> : crdoet=Llamada .getcoste () ></td> ‘ itd>et-Llamada.getFecha () ¥></td> </tr> <)> </table> <br/> </center> </body> </ntml> factura.jsp <t@page contentType=" ace l SAPiTULO 5 A8 e Antesn <br/><br/> <#ValidacionForm usuario. Walidacionge eeattbute(rvatiancs F h2>El usuario ee ee Spe sAOROGUAEE-gstnttrinn (precion SEA rr teense Voe/ps </ha> </center> </body> </ntml> 2.4 Clase ActionForm a mo vimos en el capitulo ante De para la gestion de los dat de Jave XHTML. ior la clase Acti tionForm facilita la creacion 05 de usuario p rocedentes de un formulario on creat na subelase de ActionForm en la que se incluyan los a Bees set/get y asociar la misma con el iembros_y miembt dbjeto. Action Servlet_y RequestProcessor ne : 2 gue ls clises ActnSenet yh en todo el proceso de instanciacion, jen auton tellenado del objeto. 2.4.1 CICLO DE VIDA DE UN ACTIONFORM 4.2.4. te nto que realiza Struts con est i ra de comprender el tratamie; sive e ae rie de vida. En la figura 26 ice waters nel Soe Me ectados por el que puede pasar un Act oF as una peticién en el Controlador. ‘procesamic Tecuperacién y ibii stados: 10s a continuacion & describir estos estad Pasem' i ando llega al Controlador una peticién cretion wie se_ determina que debe ‘ser una & cli izado, iiForm que almacene los datos de yg it? ima, Na com ido mediante el atributo scope del elemento ae ee ae ‘de no encontrarla, el Controlador procederé a la era’ és una nueva instancia y a su almacenamiento en oan especificado. Como ya se indicé al principio del capitulo durante el analiss rocesamiento de una peticién, este proceso es realizado id Inétodo processActionF ‘orm() del objeto RequestProcessor. Recuperacién. Retomando el proceso descrito anteriormente, sj : encuentra una instancia de ActionForm asociada al tipo de Peticin tn curso, el Controlador obtiene una referencia a dicha instan, para su reutilizacién. Limpieza. Una vez que el Controlador dispone de la referencia objeto ActionForm (nuevo 0 ya existente), procede a invocar a) método reset() del mismo. El programador puede sobrescribir este método e incluir algin tipo de operacién de limpieza 9 inicializacion de los datos miembro del bean, a fin de que existencia de datos previos (algo que puede suceder al reutilizar instancias ya existentes) no desvirtite el nuevo estado de ies Rellenado. Tras el reseteo de Ja instancia el Controlador procedea tellenar los datos miembro de la misma con el contenido del formulario enviado en la peticion. Para llevar a cabo esta operaciin el Controlador realiza de forma automética las conversiones de - datos necesarias y posteriormente invoca a los métodos sett) — Rr — : SSCS nema oy us in establecidos por la ria pee oe a método validate() €s el que se nce cone : ‘ a Formate del public ActionErrors() validates , ef) La Ilamada al método objeto ActionErrors con pa diteO devolves at de validacién. Si cat Titaeg ontrolador én. Si el valor devuel eS null, entonces el Controlador Ito por el método es disnee peticion y en vez de i cancelari | distinto de ets Ginn ee. cae Pde tpt del a ale 9 del objeto Action atributo input del elemento <action>, que noma meet misma pagina desde la que se lanzé6 la eee ‘suele ser la fn. Por ejemplo, dada la siguiente definicion del elemento ‘<action>: <action name= “LoginForm” path="“flogin,jsp”/> En caso de que el método validate() del objeto LoginForm devuelva un valor distinto de mull al ser invocado, el usuario seri redirigido a la pagina login jsp. Se puede impedir la llamada al método validate) det objeto ‘ActionForm para una determinada accién, especificando el valor false en el atributo validate del elemento <action> correspondiente. De manera predeterminada la validacion de objetos ActionF om se encuentra habilitada. La siguiente implementacién de ejemplo del método validate) Ponerara un err en caso de qe a login’ de! campo psa del bean fuera inferior a8 caracteres: ee public ActionErrors validate () { act ionscrors erroresemu}i Te (enia.pasaword.leagth()<8){ ; errores=new actiongrrors() i errores.add (new ‘actionMessage ("EXt0="* "error -PABSWOTE. LowLengey "), } yeturn exroresi mostrar los mensajes de los errores gen, rial la pagina a Ia que ha sido redirigido 9 Usual utilizaremos el tag <html:errors/>. Este celemegity Tecorre todo, : objetos de error registrados en ActionErrors y, para cada uno de ilos, muestra en un linea con el mensaje de error asocia gr ' lugar de la pagina donde se encuentra el elemento, 4.2.5 ActionErrors y ActionMessage Tal y como se acaba de indicar en el punto anterior, la clase ActionErroys encapsula los mensajes de error generados en el interior del método validates un ActionForm. Cada error esta descrito a su vez mediante un a ‘ActionMessage, el cual encapsula la clave del mensaje de error asociado, Ly, mensajes de error con SUS claves correspondientes se registran en el archiys ApplicationResource properties. Para afiadir un error a la coleccién ActionErrors se utilizara el métods add() de esta clase, pasando como argumento en la Hamada 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 tGnicamente el mensaje asociado a esa propiedad. En el ejemplo de método vatidate() presentado en el punto anterior se crea un objeto ActionErrors formado por un tinico error, emor_cuyo mensaje asociado se encuentra registrado en el archivo Ei a la clave “error.password.lowlength”. PRACTICA 43. CONTROL DE DATOS DE REGISTRO ot ee pies : ‘ ae ae - . wep Se MAL 2 c ee APTOS Asso Any ve ESDUT ay ‘Los 10S para considerar validos datos serén los si m aul Los campos usuario y password . lentes: an obligato + El password introducido en se, ios. 1 ass gundo hy e MAE debe coinciir con La direccién de correo electtonico deberi cy ontar con ef cardcter @ Registro de usuarios Noubre = [-———— Apdides:§ [———— Una: | Password: | [> Repetz Passwort [—— ae 7 Bee] ee Fig. 27. Pagina de registro de usuarios En caso de incumplirse alguno de los criterios de validacion anteriores | usuario seré mantenido en la propia pagina de registro, indicindole mediante algin mensaje descriptivo el motivo del error. Desarrollo Los anteriores criterios de validacit validate() de la clase RegistroForm, creant -criterio ineumplido. {on serin codificados dentro del método do un objeto ActionMessage por cada En cuanto a los mensajes de error, serin registrados en el archivo de .. Utilizando un elemento <html:errors> he diente al lado de cada $08 con sus correspondientes cla a tipo de error mostraremos el mensaje correspon Listado ‘A continuacion mos! este proceso traremos tnicamente el contenido de los involucrados en de validacion. ationResource properties correspondientes claves seran: Applic: mensajes de error con sus error.usuarionEI campo ‘luazto 80 Tus J<SEsaalaags seword=El campo password nO puede estar vacio pebe introducir una direccién de correo vaij, =£1 password introducido en deauste 3 Los error. pai error-emaile! error. password. nomat' lugar no coincide con el primero RegistroForm package javabeans; import javax.serviet .http-HttpServletRequest, import org-apache.struts.action.*; public class RegistroForm extends org.apache.struts.action.ActionForm { private String nombre; private String apellidos; private String usuario, private String password; ANALISES Dey, ii | } public void setUsuarioist:: this-usuario = usuario, “#9 ( } 3 public String getPasswora() ; return password; ; } public void setPasswora(st tippge o this.password = Password) { Password, } public String getPasswordrep() | return passwordrep; } public void setPasswordrep (str Ting passwordrep) | this passwordrep = pasewordre, x } public String getEmail() { return email; } public void setEmail (string emai this.email = email; é } public ActionErrors validate (Acti BttpServletReque: ActionErrors errors-new ActionErrors(); //comprueba si se ha suministrado u {fel campo usuario 4£(usuario=-nul1| |usuario.equals(**)){ errors.add("usuario", new ActionMessage("error.usuario"}); } ffeomprueba si se ha suministrado un valor para _ f/el campo password ‘null | [password.equals("*)){ errors.add ("password”. s new actionMessage("erzor-password”))7 128_ STRUTS. errors .add (*passwordnomateh®, new actionMessage ("ErrOr.Password, Jyeompritebs Hi Ta: @lrece1a) Haieead] eae tf (email. indexof ("@")==-1) { errors.add ("email", new actionMessage ("error.emailn)), } return errors? } registro.jsp <tepage content Type="text /htmL"*> <#epage pageEncoding="UTF-8"%> <¥@ taglib uri-http: //struts.apache.org/tags-logic prefix="logic" > ete taglib uri-http://struts.apache.org/tags-bean prefix="bean" %> <4@ taglib uri-http://struts.apache.org/tags-htm1 prefix="html" %> <!DOCTYPE HTML PUBLIC "-//W3C//DID HTML 4.01 Transitional//EN" whttp: //www.w3 .org/TR/html4/loose.dtd"> <html :html> <body> <center> <bi>Registro de usuarios</h1> <html: form action="/registrar" <table> A ; method="POST"> —__CAriny — RO iL et gy <tdsUsuario:</ta, OES. 1 aS i etdochtml :text pr <td>chtml :error, </tr> <tr> ‘Operty, © Proper: <td>Password: </tas <td><html password provers <td>chtml :errors </tr> <tr> <tdoRepetir Password: </eg <td><html :password prop etd>chtml:errors propert </tr> i <tr> <td>Email:</ta> <td><html:text proper <td><htm: </tr> </htm1:£orm> <br/> </center> </body> </html :html> ‘ 4.3 CONTROL DE EXCEPCIONES EN STRUTS else ‘ ‘lizados pot las Una vez validados los datos de usuario, ésos podrin st se ee las de accién para su procesamiento. Durante hs ie PB es que el desarrollador debe ser capa” de gestionar. 130_STRUTS_—_ En Struts las excepciones dentro de una clase de accién = das de dos maneras ma = + Utilizando bloques try-catch. Constituye la manera ‘ fi icaciones Java, inckyende a capturar excepciones en aplic re de las mismas dentro del propio ‘cédigo de la aplicacion, 2 captura « Mediante uo control declarativo de excepciones. En este captura de excepcion re tue se afaden al archivo de configuracign especiales = config.xml. Sera este mecanismo de control el que anali Cems en. este apartado. es se realiza mediante unas eti 4.3.1 Gestion declarativa de excepciones A fin de evitar el uso de incémodos bloque fry-catch gestionar las excepeiones dentro del propio o6digo de apie proporciona un elemento llamado <exception> que permite realizar pea Strus pe cpriones desde el archivo de configuracion de la aplicacion, capture de Hay que recalcar que este tipo de control sélo pued aquellas excepciones que se producen en las eabtlaer aetie ae ae = pero n0 en el Modelo o en las clases ActionForm, wo El elemento <excepti Me archivo ee pase vex fuctuido, en los Inearcs diferent = Dentro del elemento <global-exceptions>. 0 ; : . En este . n se control Se ee para todos ‘cokes Poe ésta se pueda producir. Para cada tipo de “excepcion quiera a se utilizara un elemento </struts-config> + Dentro de un elemento capturada tnicamente si cc" En este caso ig a la que hace referencia e} duce en ej captura de Ia exennne, Me. Enel sy Bye em iin 96 misacciones.EjemploAction. Slo. se wan Semplo ta <action-mappings> <actic ="misacci on type="misacciones Ejemplo Act fion” | > <exception.../> </action> </action-mappings> 4.3.2 Implementaci6n de la gestién declarativa de excepciones Cuando dentro de un objeto Action se produce una excepcién que ha s declarada mediante el elemento <exception>, bien como una ce ze ien como una excepcién asociada a esa accién, Struts genera un he ‘ActionErrors con el ActionMessage asociado a la excepcién y transfiere el control dela aplicacién al recurso indicado en el propio elemento <exception> Todo este proceso se controla a través de los atributos del elemento <exception>, cuyos valores determinan los distintos parametros relativos a la gestion de la excepcidn. Estos atributos son: = type. Nombre de la clase de excepcién que se vaa capturar. = key. Nombre de Ja clave definida en el archivo de recursos ApplicationResource-properties asociada al mensaje de error. Esta clave sera utilizada para construir el objeto ActionMessaze. i dgil a ido el usuario ath. URL relativa a la pagina JSP donde sera trasferi o > u caso de que se produzca Ja excepcién, En el interior & esta pagina podremos hacer us del elemento. <himlerrors para acceder al mensaje de error asociado a la excepclon- smmuTs 432, STRUTS pn vez de redirigir al usuario @ una pagi : E eee podemos optar por realizar un contro} mee de i de la excepcién. En este caso tendremos que crear ur “n especial para el tratamiento de la excepein, clase que debers referenciada en este atributo a fin de que Struts oe objeto de la misma y transferirla el control del ota mee 6 alii se produzca la excepcion. Més adelante analizaremos con detalje a proceso. Para comprender el funcionamiento del control declarativo de ex; cepciong vamos a incluir un control de este tipo en la aplicacion que desarrollamog ati prictica 3.1 relativa a la informacion sobre llamadas realizadas. Lo que haremos sera controlar una excepcién personalizada ae produciré desde 12 propia aplicacién en caso de que el usuario validady 1, Fisponga de teléfones asociados, redirigiéndole a una pégina Mamaia “sintelefonos jsp” donde se le informard de esta situacion. Lo primero sera definir la clase de excepcién, a la que llamaremos “ginTelefonosException” y cuyo cédigo sera tan simple como el que se indica en el siguiente listado: package excepciones; public class SinTelefonosException extends Exception{ } Como vemos esta clase hereda toda la funcionalidad que necesitamos de Exception, no siendo necesario sobrescribir o afiadir método alguno. Por otro lado, tendremos que modificar la clase ValidarAction para que en de que el usuario no disponga de teléfonos asociados se lance la excepcién. He aqui el cédigo de esta clase, indicandose las modificaciones realizadas en fondo //obtiene 108 datos dey //conexi : //definidos en wel . md getServlet Context ( eer ; SetInitea, new GestionClientes (ariy, ValidacionForm vf= (valida if (gc. validar (vf)) { GestionTelefonos gt~ new Gest ionTelefonos (ari 7/si no dispone de telstonos _ //se lanza 1a excepcién if (gt ..getTelefonos (vE .getPassword()) -Bize()==0){ throw new SinTelefonoszxception(); eu} f vf .setTelefonos gt .getTelefonos (vE.getPassword! xeturn mapping. findForward(" } else{ vE.setMensaje("<h2>Conbinacién de u y password incorrecta!</n2>" yeturn mapping. findForvard ("error") ; } i nS cia sa ice i sadiremos en él archivo ApplicationResource.propertes Seguidamente, afiadirem: eee _ mensaje de error que queremos mostrar al usuario con su cl telefonos registrados! que redireceionaremos al gintelefanos.sp”. El al usuario: i i e ~ error.sintelefonos=El usuario no tiene A i it la ‘A continuacién, crearemos la pagina ISP a la que, como ya hemos indicado, ae 4 muy sencillo, tan sélo mostrard el mensii® ee ore he 34_STRUTS ease spomrenicre! coding="UTF-8"¥> sneep: //stxuts-apache.org/taga-html ctepage cont prefixerhtml” * : —eanocrven ise, POREES Sine TaD 4.01 ‘transitional//EN" 4 <html> . <head> vmeta hetp-equive"content-Type" content= "text /he ml; charset=UTF-8"> <title»Pagina de error chtml:errors/> Por iiltimo, registraremos el elemento con los dat captura de la excepcién. Este elemento lo incluiremos dentro ae ee asociado a ValidarAction: action input="/" name="ValidacionForm" path="/validar" scope="request" type="servlets.Validaraction"> message-resources parameter="com.myapp. gt, “Struts “op el que in exoepoidn EJ método execute() de ExceptionHandler es Action, deslarando, ademas de los cuatro parimetros gue proporcionan al método informacion re ‘uy similar al execute) de de éste, otros i £, Ottos dos adicio esac Te public ActionForward execute(Exception ex, ExceptionConfig config, ActionMapping mapping, ActionForm form, HitpServietRequest request, HtpServletResponse response) throws ServletException Estos dos nuevos parametros son: = ex. Este parametro contiene al objeto Exception generado en la excepcion. ionConti | que s¢ . Se trata de un objeto ExceptionConfig en © 3 ee, toda la informacion ‘almacenada en el elemento - asociado a la excepei6n. 136_STRUTS tada Ja clase para el tratamiento de la to con el que Se Va a capturar ja it a forma, en el momento en de su atributo handler. De est cl ce ae Me crear un objeto de Ia subclase de ExceptionHi * Prodi control al mismo invocando & st método execute(). andes Paar, Como podemos compro ActionForward asociado 2 1a vista a 18 después de tratar la excepci6n. Supongamos que en el caso del ejemplo anterior, en 4a usuario o ls pagina “sintelefonos,jp” al producirse 1a excepein, quisi a word del usuario en una variable de ee 8 Pot ejemplo almacenar el pass después a una nueva pagina de alta de teléfonos llamada “telefonos,jsp” direvoién virtual asociada en struts-config.xmil es “alta”. > Cuyg La clase para la gestién de Ia excepeién que tendriamos que impl cn esta situacién podria ser: lementar package excepciones; public class Gestion extends ExceptionHandler{ public ActionForward execute (Exception ex, ExceptionConfig config, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException{ HttpSession s-request .getSession() ; //cecuperacién del bean que almacena /(los credenciales del usuario Ra ame eea cone) emcee: Una vez. implement que registrarla en el elemen ybar, este método también debe devolver que tendré que ser tedirigido ¢ 4° CAPTULO « wy tg te cuanto al registro de la ex, jadica a continuacién se ODN ea ot ara “a on co + Guedarig on input="/" namesry, path: scope="re, type="servie, , el contenido de la propiedad “titulo’ tet de Java Rite parameter Recupera el valor de un parémetro e eto enviad en | aya voriable JSP. Esta variable tenda ambit ato en Ia Petco y to cciones de la misma pagi le pagina y almacena en desde otras ace la misma pagina JSP. Podra ser refi Entre sus atributos destacamos: = id. Nombre o identificador asignado ala g Vatiable = name. Nombre del pardmetro cuyo valor se @ pases 0 valor se quiere almaces value. En caso de que no se haya enviado en la parimetro con el nombre indicado en name, # adeue ee variable el valor definido en este atributo, El siguiente ejemplo recupera el valor del parimetro “password” y lo muestra mas adelante en la misma pagina: am ‘ El password enviado vale:

Como se puede observar en este ejemplo, dado que lo que contiens Une variable JSP es una referencia a un objeto, podemos utilizar también la accion write para acceder a este tipo de variables. 5.1.3 cookie Recupera el valor de una cookie enviada en 1a peticién y lo almacena en ‘wa variable JSP. 4g_STRUTS_ Los principales atributos de 12 accién son: jd, Nombre o identificador asignado a la variable, «name, Nombre de Ia cookie cuyo valor Se quiere alm variable mh + yalue, En caso de que no se haya enviado en la peticign yj valiie.con el nombre indicado en ame, se asignaré a la yar valor indicado en este atributo. Vatibje siguiente ejemplo muestra en la pagina el contenido de jy “usuario”, mostrandose el valor “sin datos” en caso de que ésta no exista: “Ke bean:coakie id-*user" name="usuario"/> epole doy 1a bienvenida a mi pagina sr./a: cbocbean:write name="user"/>

5.1.4 header Recupera el valor de un encabezado enviado en la petici6 enuna variable JSP. Sanna ‘Al igual que en las dos acciones anteriores los princi i dicen principales atributos de = id. Nombre o identificador asignado a la variable. name. Ni i aie Ninel iesoeall ye ilo aul arom * yalue. En caso de que no se haya enviado en la peticién ni : > hay peticién ningin _ eneabezado con el nombre indicado en name, se asignard a la swt ae sgeos de cada idioma puedan res spose ducidos directamente en la — archivos de Los principales atributos de esta accién son = key. Clave asociada en a ees Application! de caracteres. Struts localizars a proper que tenga la clave especificada oy 14 T¥0 de re pagina. ‘SR este atributo y tics a Ia cade CUTS el \o mostrar en i name. En vez de suministrar di clave se puede extraer ésta de un identificador del objeto se irectamente en key of objeto, en cuy indicard en este atribu «property. Nombre de la. pro que contiene la clave del oo Mf del objeto india = seope. Ambito del objeto especificado en name indo que tenemos registrada la siguiente entra recursos: en el archivo de struts. message=Struts is easy El bloque de acciones que se muestra continuacin almacena el nom de a clave anterior en la propiedad “clave” de un objeto de la ei javabeans.Datos, mostrando a continuacién el mensaje asociado a dicha clave: _ cboMensaje: _ eha> tuna referencia a un objeto Ei Sta accién almacena en una variable JSP abjeto String creado por Ia en la aplicacién 0, en su defecto, un nuevo 6n a partir de una determinada cadena de texto. sa eS 144_STRUTS_ 7 2 a jos atrbutos més signifieatives Proporcionados yyy | Entre los 4 ai tenemos id, Nombre o identificador asignado a Ia variable Jgp + id.Nombre ; e. Nombre del objeto existente en cualquiera de log + mame: Mn cuya referencia serd almacenada en la varighye "0g aplicacién cuy . y. Si se especifica este atributo en la accién, a la variable JSP la referencia al objeto indicadg f: Fe de rd en el valor de la propiedad de} obj oy specifica en este atributo. Por ejemplo, si gj nae Ttributo name es “mipersona” y el de property es “apetjq variable JSP indicada en id se almacenard una referencia gs devuelto (String en este caso) por la Hamada a SetApellidoy bi el bean “mipersona”. propert asignar se alma nombre se + scope, Ambito donde se debe localizar al objeto especteiy pam. Sino se emplea este atributo el objeto serd buscado enige jos ambitos de la aplicacion siguiendo el orden: page, rays” session y application. ‘ + toScope. Indica el ambit en el que se almacenara la refeengy asignada a la variable JSP. Si no se especifica este atin 4 variable JSP tendré Ambito de pégina, Para entender mejor el funcionamiento de la accién define vamos a pengp en el siguiente ejemplo: supongamos que tenemos una clase de tipo JavaBen llamada “Datos” que encapsula una cadena de caracteres dentro de la propiedai “valor”. Desde una pégina inicio.jsp creamos una instancia de la misma y redireccionamos al usuario a otra pagina llamada paginal jsp, tal y como se indica a continuacién: <#response. sendRedirect ("paginal.jsp") ; %> __,, Por su parte, paginal jsp utilizard la accién define para almacenar ¢n una Variable JSP el objeto obj con Ambito request para después pasar la petciin pean:define scope: ten cuanto a pagina2jsp, sta el contenid na de respuesta el contenido pig ISP creada en pagina! jsp Hetrewcite nase: utilizar et clemeng de la propiedad ae Write pra lor del objeto, De esta manera, al solicitar 1a gguario recibira una pagina de respuesta Pégina inicio, en la que le ape Sm “cadena de prueba Datos’ 51.7 page Almacena en una variable JSP a uno de los objey ge que puedan ser referenciados posteriomnente dee slows oo SP afin {ibreria bean, como por ejemplo write, lesde alguna otra accién de la Los atributos disponibles para esta accién son = id. Nombre de la variable JSP en la que se slmacenar’ al objeto. lareferencia = property. Nombre del objeto implicit ISP (page, request response, session, application o config). So peaiabate 5.1.8 size ‘Almacena en una variable JSP el niimero de elementos de un array 0 coleccion. Sus atributos son: id, Nombre o identificador de la variable JSP. name. Nombre del objeto en el que se encuentra la coleeci6n. property. Propiedad del objeto espeificado en name que conte Ta coleccién cuyo tamafo se almacenari en la variable. Si no se indica ningtin valor para este atributo se considerara al propio bjeto indicado en name como el objea de oles. + scope. Ambito en el que se encuentra el objeto indic $i no se utiliza este atributo se buscard el obj Ambitos de la aplicacién, siguiendo el mismo en acciones anteriores. critetio ings = collection. Como alternativa a los atributos anteriores indicar directamente en este atributo, mediante una : el objeto de coleccién 0 array cuyo tamafio debe ser ors mace Ja variable JSP. Imacenago? siguiente ejemplo nos muestra el mlimero de autores de un 1 objeto “libro” se encuentra almacenado en una variable de sesién libro, propiedades, autores, contiene la coleccién con los nombres de ida luna. de sys mismo: autores dg £1 nimero de autores del libro es: 5,2 LIBRERIA LOGIC En Ia libraria logic de Struts encontramos un amplio abanico d con las que podemos realizar cualquier operacién de control de flujo tence en la pagina, como la generaci6n de resultados diferentes en funcién de uy condicién, la iteracién sobre coleceiones de objetos, etc. Todo ello sin necesidad de escribir una sola linea de cédigo Java en la pagina. _______ Las acciones logic se encuentran registradas en el archi as incluido en Ia libreria struts-core-1.3.9,jar. Para poder fie: ee ncluir a siguiente referencia tagiib en la pagina JSP: mi Carituto s om oe 52.4 equal Evaliia el contenido anidado de Ig anc atributos €s igual a la constante indicate Sich dag puede se numérica 0 String, segin la naturaleza de Atta value. Laggan le los ralores aco _ ae El formato de utilizacién de esta accign ser ey min seria pues: Como ya se ha indicado, el atributo value cumple! si el usuario Janza una solictud de la pagina inicio.jsp le aparecer eng senate ' navegador una pigina como la que se indica en la figura 28. oni ae eae ||) Gh) trent [in i Tip locos: 60 mnebenézoaecen%c0.ne_equalnuebs La condicién se cumple! Pégina de resultados Fig. 28. Aspecto de la pagina de respuesta Los atributos cookie, parameter, header i i > 5 y name no son excluyentes entre pases utilizar més de uno de ellos en unia misma accidn, En este caso ¢ ‘anidado de s6lo sera evaluado si la constante tos atributos ee con los datos indicados en todos y cada uno de Volviendo al ejemplo oa i lamada Di erior, supongamos que tenemos ademas una clase ee ‘con una propiedad pee Ae almacena valores de tipo entero, incluyéndose ator, ‘ndica a continuacién: HOT a Diy : pagina de result En este caso se compararé el nimero 35 con el parimetro “pa” valor de la propiedad “numero” del objeto de la clase Datos inet pigina anterior, como la condicién de igualdad solo se cumple con el rari “par” (el valor de la propiedad “numero” del objeto es igual a 10) el cuerpo accion no sera evaluado, mostrandose al usuario la pigina indicada en la al lanzar la solicitud de inicio,jsp. Y con el instanciado de la Ee : io [Pareto Gain Yer Emory teronmtar aie | oF ie © 2) al | “foo 0 B) fe ocabst:0084/prurbar2ts Si Fig. 29. Peigina de respuesta recibida al sliciar mc isp 5.2.2 notEqual Evalia el co sus atributos no €s ii exactamente de los mism™ ido anidado de la accién si el dato especificadg al al valor de la constante indicada en value, pete ‘os atributos que equal con idéntico significado, "POte on equal, en una misma accion norkgual py bitos cookie, parameter, header Y name, aunque en est to especificado en uno de ellos sea diferente Jue para el cuerpo de la accién sea evaluado, | Al igual que sucede aparecer los atri bastari con que el da constante indicada en val 5.2.3 greaterEqual, lessEqual, greaterThan y lessThan Se trata de cuatro acciones que tienen la misma estructura y atributos gy las dos anteriores, diferenciéndose de éstas y entre ellas en la condicién para qu q contenido anidado de la accién sea evaluado. El eriteio seré. que el dato indicado en los atributos cookie, heaie parameter y name sea mayor o igual que la constante indicada en value pare accién greaterEqual, menor 0 igual para lessEqual, mayor para greaterThan y menor para lessThan. Si en una misma accién de cualquiera de estas cuatro se emplean mas de un atributo selector de dato (cookie, parameter, header y name), la condicién se aplicard sobre cada uno de los datos indicados, evaludndose el cuerpo de la accién sila condicién se cumple en todos ellos. 5.2.4 match Evalia el contenido anidado de la accién si el dato especificado en sus atributos contiene a la constante indicada en value. _ demas de disponer de los mismos atributos analizados en las acciones anteriores, match incluye el atributo location, el cual puede tomar Jos valores denny © tt. Si se indica el valor “star, la constante especificada en vabe evalado srisci Prmcipio del dato para que el contenido de la accién ste aa fae aS a as de location es “end” la constante deberd aparecet jue no se ‘il stante sera buscada en cualquier parte del dato emplee este atributo la cons! ‘tenemos une pina inicio jsp on la siguiente instuccién: a cairo, cpresponse sendRedirect sprueba.isp?pa: ¥ en Ja pégina prueba jsp incluimos els iguiente cig , igo: El cuerpo de la accién match no seré eval catch’ se encuentra incluido en la cadena “Prach ’ rai reba Mada como Pardmetro, no esti sitado al ea speci luado, ya que, de la misma tal fica en location. ma tal y Si en una misma accién se emplean mis d parameter, header y name) | tun atributo selector de dato (cookie, 1a busqueda de k; Bt ia ; sabre cada uno de los datos indicados, Bente ieraa acon coincidencia se da en alguno de ellos. ‘uerpo de la acciém sila 5.2.5 noMatch Dispone de los mismos atributos ¢ los mis tos que match aunque, a diferencia de ét evaluard su contenido si el dato no contiene a la constante Suuicainca aha Encaso de emplear mas de un atributo selector de dato el contenido sera aaah siempre y cuando la constante no esté contenida en ninguno de los datos 5.2.6 forward Esta accion transfiere 1a peticion del usuario a fa URL asociada a uno de “10s elementos globales definidos en el archivo de configuracion struts- configxml, indicando a través de su tinico ‘atributo name el nombre del elemento ‘ utilizado. teminada URL, pdiendo enviar ida de distintas Redirecoiona al usuario a_una de ) de ser especifica eS pardmetros en la misma. Esta URL Ps a ee por Ia accién, ma cegin los atributos utilizados por 1a accién, més Concretamente, en = srmas segiin 108 3 Leo a rio atributos que se indican a continuaci i action. Nombre del elemento 4 a donde sera redirigido el usuario. global que rere aq destino forward. Nombre del elemento global a eu redireccionado el usuario. YOURL sey la URL absoluta del destino, + href. Especific + page. URL relativa del destino. diciatiradined i A Fn una determinada acciOn redirect s6lo podra definirse ung q. atributos anteriores. Por otro lado, en todos los casos se aplicaré autométicamente la re en URL para mantener el identificador de sesiGn en caso de que se desact de cookies por el usuario. eScritin, Ve el usy Para enviar pardmetros en la URL podrén emplearse los siguiens atributos de la acci6n: = paramld. Nombre del parémetro que se quiere enviar. * paramName. Nombre del objeto que sera utilizado como valor de parémetro especificado en paramld. + paramProperty. Propiedad del objeto indicado en paramNane cuyo valor sera enviado como parametro, en vez del propio objeto, " paramScope. Ambito del objeto especificado en paramName. Si no se utiliza este atributo se intentard localizar el objeto en todos los ambitos de la aplicacién, siguiendo el orden: page, request, session y application, name. Como alternativa a paramld y paramName pueit especificarse en el atributo name un objeto coleccién de tipo JavautilMap cuyo contenido sera enviado en parimetros de lt URL, siendo la clave de cada elemento el nombre del parimettoy el propio elemento el valor del mismo, property. Si se utiliza este seré enviada en los parame ™ 1 Coleg Ia propiedad del objeto ego URL ser indica en este atributo, ado en nam, Yeamos un ejemplo de utilizacién ge Jo anterior que tenemos una sae esta accién seed “mumero” que almacena valores name repeccionaria al usuario a Ia URL. asociady Tics e cando como parametro en la URL el valor fe el pe Dat jem?! at instanciado en la propia pagina ebody bgcol ejsp:useBean id="ob La pagina destino por su parte uilizard las siuients avo lcontenido del pardmetro “edad” en la pagina, visulizindose: “Edad. 34°. ebody> 5.2.8 iterate Esta accién recorre todos los elementos contenidos en una eyaluando para cada uno de ellos el contenido anidado de la accion. La coleccién sobre la que se va a iterar debe ser de uno de los siguentes tipos: = Unarray de tipos primitivos u objetos Java = Un objeto java.util.Colleetion «= Unobjeto java-util. Enumeration « Unobjeto java.util Iterator « Unobjeto java.util.Map sia coleecion puede ser especificada de dos posibles mancras, sea, Oe logic:iterate> se emplee: 5, SeBin cy de los dos siguient es atributos de + collection, Representa una expresiOn JSP que dey Ive coleccién a recorrer. «name, Nombre del objeto que contiene Ia coleccién En el caso de que se uilice el atributo name, podrén especificarse tan Imbie Ios atributos: + property. Nombre de la propiedad del objeto indicado en que contiene la coleccién. ame = scope. Ambito del objeto indicado en name. Aparte de los atributos anteriores, la acci6n iterate dispone de estos oto + id. Nombre o identificador de la variable JSP que almacenaré referencia al elemento de la coleccién en cada iteracién. Su ambit esta limitado a la pgina. : " indexld. Nombre o identificador de la variable JSP en donde se almacenar el indice de la iteracién en curso. Su Ambito esi limitado a la pagina. = type. Nombre cualificado de la clase a la que pertenecen los elementos de la coleccién. * length. Numero de iteraciones que se realizaran sobre la coleccién. Sino se especifica se recorreré completamente la coleccién. En el siguiente ejemplo se muestra en una pagina la li mn lista de nombres poxiets en una coleccién de ambito de sesién llamada “listado”, para, « luacién, indicar el nimero de nombres presentados: slogic:iterate name="listado" scope="session" id="nombre" pescriP practice 5.1, LISTADO DE LLAMADAs = S CON Tag pcion °S STRUTS Se trata de realizar la misma apc, ndo los scriptlets de cédigo Jaya qo o™ lininat : va de Pr Gpicamente etiquetas XHTML y tags de Strutsc, —* pesarrollo Los dnicos componentes que tendremos amerior seri las vistas listado,sp pfu, iones.sp, p aver registro.jsP 2° incluian ningun tipo de scriptlet, Listados Seguidamente mostraremos el mmenefonadas anteriormente, <#@ taglib urishttp://st prefix="html" %> ‘<{DOCTYPE HTML PUBLIC "-//W3C//DTD # ‘Transitional//EN* shetp: //www.w3 .org/TR/html4/loose.dta"> shtml :html> «meta http-equiv="Content-Type" com text/html: charset -UTF-8"> eritlesJeP Page «
a “pisopetones para el listado de lamadag (y chemi:form action="/listado" methods fs cp> Seleccione ntimero de teléfono:
EB


Seleccione tipo de llamadas:
0){ request . setAttribute ("mensajes* mensajes return mapping. findForward( sualiza"); } else{ return mapping. findForward (*sinnensai Ee 162_ STRUTS Operaciones package model0r import java-eql-*7 import javabeans.*7 import java.util.*7 public class operaciones { /imétodo comin para 1a obtencién //de conexiones public Connection getc on cn=null; onnect ion() { Connecti try{ class. forName ("sun.jdbe. odbc. JdbeOdbeDriverny cn=riverNanager .getConnection ("jdbe:edbe:me rmensajes *); } catch (Exception e) {e.printStackTrace () ;} return en; } public ArrayList obtenerMensajes (String destino) { Connection cn=null; ArrayList mensajes=null; Statement st? ResultSet rs; try{ cn=getConnection () ; st=cn.createStatement () ; String tsql; teqle"select * from mensajes where destinatario='"+destino+"'"; catch (Exception ¢) ( Ve.prin return (mensajes) , } public void rabaMensaye (y, connection *eMensajey Statement st ResultSet rs; exy{ en=getConne. string tsq //a partir d //la cadena s\ OL pa tsql="Insert teql etDestino st.execute con.close() } catch(Exception e inicio.jsp <{DOCTYPE HIML PUBLIC "-//W3¢//DTD HIME 4 Transitional//EN" whttp: //www .w3 .org/TR/html4/Loose.dtd*>


/struts.apache.org/tags-h Enviar mengaje

164_ STRUTS npreviolectura"> /ntml :Link> Link forward= html: Leer mensajes<,
envio.jsP weext/neml"$> uTF-8"¥> Jateuts. apache .org/tags-bea: crnocryer ami puBLtC *-//W2¢//22D 2TMba<03) Transitional//EN" snttp: //www.w3.org/TR/html4/Leose- dears
chisGeneracién de mensajes chtml:form action="/grabar" method="POST" >

Datos del mensaj Introduzea destinatari:

/b>

jestino" />
mostrar-btm entml>
ebr/>
Mensajes para ="nombre" name="nombre"/> etr>cth>Remitente clogic: iterate id="mensaje" name="mensajes* scope="request"> etr>ctd>cbean:write names"mensaje” property="texton/> ebr/>
ehtml:1ink forward="inicio">Inicio nomensajes.jsP esepage contentTypa="text/html"*7 etepage pageEncoding="UTF-8"*> <#@ page import="javabeans.*, java.util. *"> <’@ taglib ur: nttp: //struts. apache. org/tags-logi, prefix="logic" %> ett 49 taglib uri-http://struts apache . org/tags-bea: prefix="bean" $> z <#@ taglib uri http: //struts.apache.org/tags-html prefix="html" &> Capitulo ¢ VALIDACION DE DATOS DE USUARIO La utilizacion del método validated) de A sjato en eapitulos anteriores, validar los datos cumin oat 8 ea vt formulario XHTML antes de que éstos sean Sah Seton se , rocesados por la aplicacién Pero este sistema de validacién requiere coditicar ¢ ee cin min as de forma manual las jneficiente, ya que la definicién de criterios de vale eee ‘ActionForm implica la repeticién de las mismas eae (eee datos en los métodos validate() de cada una de las clases, rae La utilizacién de validadores simplifica enormemente el proceso de yalidacion de datos de usuario en una aplicacién Struts al ieee un mecanismo de validaci6n automatica, de tipo declarativo, que evita la codificacién de estas tareas desde cddigo, permitiendo ademas la validacién de los datos tanto enel cliente como en el servidor. 6.1 COMPONENTES DE UN VALIDADOR La utilizacion de validadores en una pagina JSP se apoya en el empleo de “una serie de componentes que proporcionan toda la funcionalidad necesaria para - Ilevar a cabo la validacién automatica y que habri que configurar adecuadamente - tneada aplicacién, estos componentes son: 55 STRUTS » Plug-in validator «Archivos de configuracion + Laclase ValidatorForm «_Arohivo de recursos ApplicationResource,properties 1 el significado y funcién de estos coy my Ta manera en que se deben utilizar los valignge st lores, Veamos 4 continuaci6 antes de entrar ¢n detalle sobre 6.1.1 Plug-in validator in validator es la cl incorporada en el API de St es automaticas dentro de una aplicacion wan ears EI plug de gestionar las validacion uedan utilizarse las validaciones automaticas en una di la determi nada Para que pt ar esta clase en el archi VO struts-co mifig xm aplicacién serd necesario registr utilizando el elemento : «plug-in className= vorg.apache .struts. validator .ValidatorPlugin"s eset-property property="pathnames” " /WEB-INF/validator-rules.xml /WEB-INF/validation.xm1"/> : value=" Este elemento dispone de un atrib s pute especificar el nombre de la clase Struts. ice aoe sat aaa Se debe indicar ademés medi: propiedad ‘4 ] ante el subelemento evalidator name="required" classnam ="org. apache.s} validator. Fic method="val. methodParams="java.lang.Object, org.apache.conmons validator. Validatoraction org.apache. commons validator org.apache.struts. action ActionNessages, org.apache.commons- validator.Validater, javax.serviet http: Retpserviet Request” meg-"errors.required"/> Cada una de estas reglas de validacion se declara medi evalidator>, definiéndose & través de sus atributos los pi re ie, de cada regla- Estos atributos son: ardmetros conga name. Nombre lice asignado a la regla de Validacign , me, Nombre de Ia clase de Struts en ta que se Meet, classna’ ‘ 'strucciones para realizar la tarea de vali idacign, definidas las in method. Método de la clase indicada en implementa la regla de validacion. classname e ms, Parimetros declarados por el métod, lo ¥ Que tlevar a cabo su funci6n. Seré el plugei Sa et neiedo peel ‘SuMentog « methodPara) necesita para encargado de apropiados en la lamada. ave asociada al mensaje de error vee ao se incumpla el criterio de alidheiba Gene Estos mensajes Se registraran en ido en ta regl, ‘ApplicationResource-properties. el archivo = msg. Cl ‘Ademés de las reglas de validacion redefini nuestras propias reglas ds eee ee las aplicaciones. Una vez creadas las clases que cup Merna ee ee rea métodos, sera necesario declararlas en el archivo Sines ae Jante en este capitulo analizaremos la creacién de reglas de ae personalizadas. 6.1.2.2 VALIDATION.XML En este archivo de configuracién el campo cuyos datos quiera validar el programador deberd asignar a cade eae lo anlar ee Oe Seen ae En el sigui n ej siguiente listado vemos un ejemplo de definicién de una regla de un formulario capturado mediante un ActionForm: ———£artr a OEY OR 7 a apaci » peep: //J2kazta-apache.or3/cceacn, “AiO be #/ dtd jy ou A eform-validation> eformset> ‘ipocrypE form-validatson PUBLIC t//mpache software Foundation//DTD. commons validator Rules Configuration 1,1 /jakarta apache .org/commons/dtds/validator 1 i few wntep:/, ge carg key="ValidacionForm. usuario" /> arg key="ValidacionForm.password" /> 6.2.3 Habilitacién de la validaci6n en cliente : Siempre que sea posible se deberia realizar la validacion de los datos de usuario en la pigina cliente, esto hard que la peticién de envio de datos al servi: éstos no cumplan con los criterios de validaciin an rendimiento det ion, sh ee Per ° Te io el de los datos en el servidor aiid i ‘tes de igor, en. servidor yen cliente, sigue! aig ey Gena oo erplicndn eS ees secciones anton ‘A fin de poder realizar la vatidac aor inyecta una serie de instrucci Ton desde salidator rytes de proceder al Structiones javascript eng aveRador, of jects on ilitar Ia validacis io de Ta peticign por Pena cliente plug-in jo babilitar la validacion en cliente afadieng PE? YE SS0 sures seereuier parte de la pagina: liendo la sigai ‘S510 suceda seri, a a accion deberd indicar a través det objeto ValidatorForm. Atributo formName el nome de nbre de ‘Asi mismo, desde el manejador del event jncluir una Hamada a la funcién javascript ce proceso © validacion. Dado que esta funcion se oes de desencadenar eh Pembre tendra el formato validateObjetoForm, siendo Objet forma dinimica, su Mijeto ValidatorForm. Ta llamada a ese método inclu eck el nombre det this. Ast guedara por tanto la pagina login.jsp del ejemplo: nO argumento el valor Onsubmit del formulario se html :html>
Formulario de autenticac: chtml:javascript formNane oe 7 Ghemi:form action="/validax" method="post" onsubmit="return validateValidacionform (this) ;*> ‘ ‘ etd>chtml:text property-"usuario"/> “Geameheml :paseword property="panaword"/>
Usuario:
Password:

chtml:submit property" gupnit” valuectValiart/> ea 17§_ STRUTS 178 STRUTS gnbep; &nbsPi chemi:reset value ="Dimpiart/>

Re spent :1ink forvard="pararegi stro" >Registresec/ie ML Langs ebr/>
entml:errozs/>
6.2.4 Mensajes de error Fl mensaje de error que se mostraré al usuario en caso de incumpl criterio de validacién es, en este ejemplo, el que viene definido con jy a errors required ene] archivo ApplicationResource.properties: clave errors.required=(0} is required. Sera también en este archivo donde se definan las cadenas que se pasarin ‘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 validacién se produce en cliente se mostraré un cuadro de didlos con el mensaje correspondiente en el momento nique se intente realizar Ia peti desde la pagina (figura 30). si Fig.30. Mensaje de error de validaciin 63 VALIDADORES PREDEFINIDOS DE sTRUTS Ya hemos visto el funcionamiento de uno de los valida se uflizan en Ia mayoria de las aplicaciones Web, e per hwenrd idamente analizaremos otros de los validadores eeeaeaias ee gc emplean. con mis frecuencia en las aplicaciones, a ia 63.1 minlength Este validador comprueba que el valor numérico suministrado en un campo sea mayor o igual a una determinada constante. ‘Ademas de los subelementos , ¢! elemento utilizado en la declaracion de este validador en validation.xml deber incluir un subelemento " en el que se indique la constante con Ja que se comparara el valor del campo. _ Laestructura de este elemento es: ae. ~ nombre valor ee ao STRUTS i J nombre de la constante (en el donde contiene el nombre ¢ ” 880 de min nombre de la variable serd el mismo, “minlength”) y sy me BI siguiente ejemplo define 1 regla de validaci6n para ef Bis de un formulario, que fuerza al usuario a la introduccién de un valor en : tagr igual o superior a 18: isn, cargo key="Registrororm.edad*/> cargi key="RegistroForm.edad.min"/> . minlength evar-value>18 En este validador vemos como el mensaje de error requi argumentos, el nombre del campo y el valor minimo. quiere de dos 6.3.2 maxlength su estructura es igual a la de minlength, validando el campo indi at one de si su valor es igual o inferior a la caibeile Se tl elemento . El siguiente ejemplo establece que el val cree debe ser igual o inferior a 600: a Sea argo name="maxlength" key="InfoForm. limite"/> : ee ength" key="InfoForm.1imite.max"/> 633 pyte, short, integer, long, float y Mediante estos validadores es) double podemos es compatible con el tipo de date mR s cams uiente re; 0 Tepresentny, 1°! COttenida cjemplo, 18 Se Sa oe comprucba que ef ira? Por el Ee ins sey sea de tipo double: 1 pone a Pe Del campo min evar-value>i : max evar-value>i0 _—_— i} soe exon ese — observar en el ejemplo y también en el archiy, Applic operties, el mensaje de error asociado a ee necesita tres pardmetros: ri nombre del campo, el valor minimo y ¢] _ Yalidagy ‘se utilizan en el ejemplo se encontrarian almacenados i, im rerumentos GUC Se ioe So InforForm.nota, — InfoForm piv ®hiyg 05 mac, respectivamente at Como se puede ationResource Pr InfoForm.n 6.3.5 floatRange Y doubleRange ue ef anterior, estos validadores comprueban qu, elimitado dentro de un determinado rango ee &l Valor gg float y double, respectivamente, pe Slo gue igual a la de intRange. + La estructin, Al igual q' campo se encuentra gn estos casos ese rango es de pO J del elemento es exactamente 6.3.6 date Comprucba que el valor del campo tiene un formato de fecha vilidg ngmpleadoForm. fecha"/> depend: carg ke Opcionalmente el elemento admite una i : variable, lamada dateParern, mediante la que se puede especificar el tipo de Renita mia pata el campo, Por ejemplo, la siguiente regla establece para el se ‘echainicio” el formato de tipo dialmes/afio: aie datePattern dd/MM/yyyy ¢ re a e sarees ‘a través de este validador obligam, e «ge al formato definido en una mascara, pe, &! £0 suse tiple “mask”. Para defnir una sa miscara ea 8 tn capo ge in varie icaci : ja vari ion de aplicaciones regulares en Java ie iliac 0s st oi sen establece que el contenido del Por ¢ var inio com -Ampo “uri” torino + "url" depends="mask" > 6.4 MENSAJES DE ERROR PERSONALIZADOS ies de error que se muestran al usuario Si queremos modificar los mensa} . Tidacibn, la mejor forma de hacero ser ‘cuando el campo incumple un criterio de val _Seguir os siguientes pasos: re sic el unensaje a archivo de reeaos E2 6 archivo de recursos: ‘ApplicationResouree:propert es eserbiriamos al Lec personalizado que queremos mostrar, asignandole wna cla Bren struts oe i i 9, Dado que los mensajes predefinidos tienen msm Merorsnomire_validador, —deberiamigg "0° ey asociad®: erente. para 1as claves personalizadas Mltae a wrrors.personalizados.nombre_validador, ” °™o gjemplo: « indicar ef mensaje @ utilizar en de se referirén en estos casos nuevo mensaje definido. PRACTICA 6.1. VALIDACION DE LOS CAMPOS DE LA PAGINA DE REGISTRO Descripcién Utilizando los validadores proporcionados por Struts vamos a definir una serie de reglas de validacién para cada uno de los seis campos incluidos en una pagina de registro de usuarios como la que se indica en la figura 31. Los criterios para considerar como validos los datos suministrados a través de estos campos serdn los siguientes: * Todos los campos serdn de obligada cumplimentacién. * El campo “password” tendra que tener una longitud minima de cuatro caracteres. * El campo “edad” debera ser de tipo entero. El campo “email” formato valido. oe Apeidoe | —————_
<{DOCTYPE form-validation PUBLIC te mostraremos el cédigo de los archivos de text 1 afadir a este archivo las siguientes lineas de 1_//mpache Software Foundation//DTD Common: é 8 Validator Rules Configuration 1.1.3//EN" wnttp://Jakarta.apache.org/conmons/dtds/validator 11 3.ata __
; svar-val,
key="Registrol ___ egistro.jsp ‘clepage contentType="text /html"*> Sepage pageEncoding-"UTP-8"t> ee taglib uri=http: //struts.apache.org/tags-neml a prefix="html" $> <|POCTYPE HIML PUBLIC "-//W3C//DTD HTML 4.01 ‘Transitional//5N" Ree cnem) javascript formMame="RegistroForm=/> chemi: form action="/registrax* method=*Py etd>Nombre: crd>chtml:text property="nombre*/> ctd>Apellidos: ctd>chtml:text property="apellidos"/> : etd>chtml:text property="usuario"/> ee ee property="password"/> ctd>chtml:text property="edad"/> : ; : os yALIDACIONES PERSONAL 17.45, ten algunas ocasiones puede ocurtirqueg,.,. SS no cubramos todas las necesidades de valida 0S Validadores splicaciOn- oe Jin estos casos, si tuvigramos que pita en 10s validadores de Struts, po, aplicar un MOS optar po a soluciones: + Sobreseribir el método validate) de nuestras propias instrucciones del vagy Form alidacin + Definir un método validador personaizag lizado, 65h Sobrescritura del método validate) ‘Anteriormente comentamos que a la hora d ValidatorForm debiamos mantener la im método yalidate() proporcionado por esta clase bi le crear la clase by plementacién por Si queremos incluir algin criterio de validacin personalizn en mes ise y, al mismo tiempo, mantener la validacién automstica propocionais ne Guts podemos sobrescribir en nuestra clase ValidaoeFor el msodo easy fachir manualmente en él las instrucciones de validaiin propia, sempre y undo agreguemos también a ésle una Hamada al método validaet) deta superclase. El formato de método validate() proporcionado por ValidatorForm y que podemos sobrescribir es el siguiente: . public ActionErrors validate(ActionMapping mapping i javax,servlet.http.HtmpServietRequest request) J Bes Re ot it Por ejemplo, supongamos que en la pagina registtosp de la prictica uisiéramos incluir un campo adicional llamado ™passwordzep”) donde et ‘deba volver a introducir el password pot segunda vez, comprobando & 199_ STRUTS continuacion que el valor introducido en el segundo campo primero. io de validacién no es impl Jos validadores proporcionados por Struts dsberlamnOPSeuae +e dae) de nuestra subelase RegistroForm © incluir en él Ine necesarias para realizar esta comprobacién. El siguiente li A quedaria la nueva implementacién de la clase RegistroForm, i muestra sombreado 1as instrucciones afiadidas: Dado que este criteri package javabeans? import org.apache. struta.validator. *; public class RegistroForm extends Validator¥orm { private string nombre; private String apellidos; private string usuario; private string passwor private string ema: public String getNombre() { return nombre; } public void setNombre (String nombre) { this.nombre = nombre; } public String getApellidos() { : return apellidos; public void setApellidos(string apellidos) { this.apellidos = apellidos; 5 this.password = pass, } public String getras, eae Teh public void setPasswo, this-passwordrep meee — ) ars i public String getemaii() ; mn email; public void setimail (string this.email = ema, J ena } ubISCPACHORECGES]varsaita(nce meee MAP mapping etRequest req) Rttpserv1 ActionErrors errors-super on a if (lpassword eine ee errors.add(*passwrds, new ActionMessa: : ge (“error error. password. -nomat.ch* 4 return errors; 6.5.2 Creacion de validadores personalizados Si queremos definir una regla de validacién que pueda ser uilizada en diversos proyectos, la solucion sera crear nuestro propio método validador. Esta operacion requiere realizar las siguientes tareas: = Implementar el método de validacién. = Registrar el validador en validator-rules.xm = Definir los mensajes de error predefinidos. = Utilizar el validador. = Implementacién de un meétodo de validacion. cere tree STRUTS —sa pene Ry ACION DEL METODO DE VALIDACIy dar de Java implementaremos el métodg Jan struts para validar el contenido de un €ampo asociagg 4 yy vocado po wtho metodo la logica necesaria para la comprobacign dt Milne ae sonalizadas. le log ge as reglas personalizada = 6.5.2.1 IMPLEMENT: En una clase esti in incluyendo en segiin nuestras pro} EI método podré Hamarse de cualquier forma, si bien debers era res Petar siguiente formato: public boolean nombre_metodo(Object ob, orgapache commons validator. ValidatorAction y, org.apache.commons.validator.Field f, org-apache.struts.action.ActionMessages msgs, org.apache.commons. validator. Validator vt, javax.servlet.http.HttpServietRequest request) Como vemos el método deberi declarar seis parimetros cuyo signitcay es el siguiente: + Object. Objeto bean que contiene el campo que serd validado, + ValidatorAction. Representa el elemento definido en validator-rules.xml, asociado a esta regla de validacion, = Field. Representa el elemento definido en validation.am) asociado al campo que esta 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 validacién * HttpServletRequest. Objeto que contiene los datos de la peticiin en curso. ee lado, el método Por otro __, g Struts el resultado de tg Tae om ine incorrect). iim (n por ejemplo, supongamos que uisiéram, c at eS ope Suministradas nS, 7° ta req Peete en obligar al usuario a incluir uy mediante uy go? Validas consin, que limitaremos @ uno de los Sghon eae eign Ua ineliremes dentro de un me Seo galcMentaremos en una clase Hamada “Person 0 “pa a de isn Onalizadg® pre ™OrdValigy close! TSMR a cing a, package validadores; jmport OFg-apache. common: public class Personalizado { til public boolean pas org.apache /1cox ida return true; } else{ xeturn false; } Yomo podemos apreciar en este céxligo, hacemos uso del metodo esttico eAsString() incluido en la clase ValidatorUtils para recuperar el valor en el campo a validar, método que requiere el bean donde se encuenira sel campo y la propiedad que lo define, a cual puede obtenersea paride 1o4_STRU 6.5.2.2 REGISTRO DEL VALIDADOR Una vez definido el método debemos registrar la nueva reg en el archivo de configuracion validator rulescerall dela eoiteaa 4 uso de ella. Para ello debemos aftadir ene queramos hacer ete ‘ ralidator> con Tos datos del vals iador, como son el nombre asi; analizag al principio del capitulo. « deberd incluir dentro del element ; «eral que se defina Ia funcién jeveserpta eae dor para realizar la validacién en client ae tend re. A esta fin : ‘Asi mismo, st subelemento Como sucede con , serd durante la pagina de aplicacién cuando esta accién sea sustituida On de Ig real. POF un tig Vamos a ver un ejemplo concreto que sirva para aclarar Imaginemos que queremos crear una aplicacién con dos paginas cuyo Conceptos, muestra en Ia figura 33. 1YO aspecta s¢ Pagina 1 ses! Contenido primero SR) tects epee vine — eropage PASEENCOi garry gey. ATRL 5g gre taglib urishttp://ser, = US apa, e:DOCTYPE HIME PUBLIC */yqy0//. " spctp: //www.w3 .org/TR/ te. chead> emeta http-equiverconte ctiles:, </head> <body> <center> <hi>ctiles:getasstring nangssy </center> rteperees <table width="so4", 25%" colspane2", oe attributestencabezadot/y </tr> <tr> <td> <tiles:insert attribute=tmena'/> </td> <td> <tiles:insert attribute="cuerpo"/> </td> </tr> </table> Creacién de piezas de contenido JSP Las piezas de contenido representan las porciones ee Ie n a los elementos <tiles:insert> durante la creacion eer ee 302_ STRUTS Por lo general estos bloques de contenido se almacenan en dado que su contenido formar PS de las paginas finales, prucdey Sbdigo XHTMLASP esténdar como acciones de Struts. Pueden Al igual que sucede con las paginas maestras, Dara vitae, ba directamente accesibles desde el cliente, estos archivos deberian GUE Pda ol directorio WEB-INF de la aplicaci6n. 81 stad Los siguientes ejemplos representan las péginas que somo contends para ls zonas definidas en Ia plantilla ner aS zag titulo.jsp <topage content Type="text/html"&> cropage pageEncoding="UIF-8"4> cuiv aligne"center" style="background-color:aqua vacnane chishplicacién de ejemplo</hi> </center> menu.jsp <t@page content Type="text/html"*> <topage pageEncoding="UTF-8"+> se taglib uri-"http: //struts.apache.org/tage-htm" prefix="html" ¢> <table> <tr> SATUS > a TAO UAC SSE Ponty <td> <a href=" </ta> </tr> </eable> ">opeigr pody!.isP xopage content Typ: xgpage pageEncoding= ext /html "45 UTE-ar4, episcontenido prim Ga3>Este es el cuerpo body2-isP content text/heminys pageEncod: ae nido si ch3>Este es el cu de 1a pag 423 Creaci6n de las paginas de aplicacion Una vez que se dispone de la plantillay de as piczs de one ie plginas de la plicacién resulta una trea temendamente ee fe seni. Para s6lo sera necesario declarar al principio de la pagina la plantilla que se vaa it = ilizar tindicar a continuacién las piezas que queremos situa en cada zona de contenido 7.2.4 Declaraci6n de la plantilla La declaracién de la plantilla se leva a cabo mediante la accion ~ tiles:insert>, utilizando en este caso el atributo page de la accién para indicar la diecoi6n relativa de la pagina maestra, Por ejemplo, suponiendo que la planillase encuentra definida en un archivo Jamado base.jsp que esta situado en el directorio WEB-INF, la declaracién de la plantillaen la pigina de aplicacion seria: Stiles:insert page= "”WEB-INF/base.jsp"> <|--Aqui referencias a paginas de contenido-> ee ree 204 _ STRUTS. Wodew Inclusion de paginas de contenido zn el interior de insert debemos indicat las piezas que que, cada zona de contenido especificada en 1a plantilla. Esta sencilla or rirads media is meckiw Aue ae 7a configuracién se sus dos atributos: «name, Nombre de Ia zona de contenido a la que hace = Este deberé coincidir con alguno de los valores de Tefen fMpute o name definidos en las acciones 108 abu <tiles:;getAsString> de la plantilla. rr value, Contenido a incluir en Ia zona especificada en wxo de zonas definidas mediante tiles:insert>, value egnes Ml ta URL relativa de la pagina de contenido, mientras °SPecitica, de <tiles:getAsString> contendra la cadena de texto one leap sustituido el elemento. ques tn el eemplo que estamos analizando, las péginas de apicacin ena figura 33 se generardn de la forma que se indica en los Time te paginal.jsp <topage content Type="text/html"*> <tepage pageEncoding="UTF-8"$> <4@ taglib uri-http: //struts.apache.org/tags-tiles prefix="tiles" t> <[--declaracién de plantilla--> <tiles:insert page="/WEB-INF/plantillas/plantilla.jsp"> <tiles:put name="titulo" % value="Pagina 1"/> <tiles:put name="encabezado" pagina2.jsP sgecige cronent exepage Past ea taglib uri eeiles:insert pag * /wee-1 13 DEFINICIONES EI mecanismo de ulilizacién de plantas gemite reutilizar eédigo en las aplicacions lenis & ae Prbilidad a la hora de crear las paginas finales daa nia oreacion de estas péginas finales donde cbservames antes, erosos elementos repetitivos, por ejemplo, en el cation @ en gnteriores vemos como el elemento <tiles:put> canst et ‘= tonas de encabezado y ment es idéntico en ambas péginas, ci ion de las iro defecto que presenta el siste eat ‘ oO # a ee senta el sistema anterior es el hecho de que cualquier cambio en la ubicacion de alguno de estos archivos de contenido implicard tener gue actualizar todas las paginas de la aplicacin donde se haga referencia a ios Jo que puede resultar en una importante fuente de errores. Ta solucién que propone Struts para estos problemas consiste en la wlilizacion de definiciones. Una definicién, como su nombre indica, define una sianera de distribuir las piezas de contenido en una plantilla, de modo que a l hora “de crear una definicién con contenido similar a otra ya existente no sea necesario volver a definir de nuevo los mismos elementos ya estzblecidos en la anterior nicién, sino que bastaré con que la nueva definicién herede a la primera y ‘redefina tinicamente aquellas zonas cuyo ‘contenido es diferente al indicado en la ee ee 206_ STRUTS na definicion definicién debemos disponer de una plantitia El desarrollo de estos elementos se lleva 2s sccién anterior. bo tal 7.3.1 Creacién de u' Antes de crear una de paginas de contenido. como explicamos en Ia se ren cuanto a las definiciones, éstas se crean en un nueva fe cuya ubicacin debera estar ing archi ado tiles-defs.xml. hiv configuracién lam z e . icad, ae plug-in> definido en struts-config, xml, tal y como se indieg a} coe d ae apitulo, Lo habitual es que tiles-defs.xml se sittie en el directorio Wep. ING del capitulo. Lo hab I a aplicaci6n. La estructura de este archivo es la que se muestra a continuacién; s-definitions PUBLIC <IDOCTYPE til _//mpache Software Foundation//DTD Tiles Configuration 1.1//EN" onttp://jakarta.apacl /struts/dtds/ tiles-config 1 1.dta"s <tiles-definitions> </tiles-definitions> Como vemos, existe un elemento <tiles-definitions> dentro del cual se incluiran todas las definiciones que se vayan a utilizar en la aplicacion, cada una de ellas en su propio elemento <definition>. 7.3.1.1 DEFINICIONES BASE Una definicién base es aquella que define explicitamente la distribucién de los contenidos de cada zona indicada en Ia plantilla, sin heredar ninguna otra definicién existente. En este tipo de definicién habr que especificar los siguientes atributos dl elemento <definition>: = name. Nombre asignado a la definicion. = path. URL relativa de la pagina maestra que contiene la plantillas partir de la que se va a crear la definicion. Sarttt099. cy, ZAC para indicar el contenido de cada sa I di Zona tio el cual dispone a su vez de tog Pic debe s: M0 <p + name. Nombre de la 20n para ig NE Sevag » value. En el caso d . eat - atributo indicara Ja Une eh oe mientras que para las zonay ns ee cadena de texto equivalente,USS8EAsS 43.12 DEFINICIONES DERIVADAS ‘A la hora de crear una definicién deri ; om derivada aqatributo ees del Sra <definition> e ee ebemos especiticar a manera, el elemento heredard todas ls defnicons rnin Be, De Srefnition® padre. Si queremos redefinir el contenide denn eeitcadas en stliaremos nuevamente el elemento <put> © de cualquiera de tas zon nas EI siguiente listado corresponde a las tres defini implementar nuevamente las paginas d. iciones que utilizaremos lel ejemplo presentado en | erior, Ia primera de ellas corresponde ala defnicin base ae 1 Marin ala base, indic&ndose en clases elementos propa de space cada pagina <tiles-definitions> = <definition name=" path="/WEB-INF/plantillas/plantilla.jsp"> eput name="titulo* value="*/> <put name="encabezado" value=" /WEB-INF/plan lo. jsp" /> <put name="menu" /WEB-INF/plantillas/nenu.jsp"/> <put cuerpo" value="*/> </definition> <definition nam put name="titulo" value="Pagina 1*/> Biss: <put name="cuerpo" ae value=" /WEB-INF/plantillas/body?.jep"/> =" .parapaginal" extends="-principal'> _ </definition> <definition name= put name="titulo" value="Bagina 2"/> sc parapagina2® extende-*-prineipe)"> eput name="cuerpo” value=*/WEB-INF/plants11a8/body2. $y. </aefinition> </tiles-definitions> 7.3.2 Paginas de aplicacién vez ereadas las definiciones, la implementacién ieee ‘remendamente sencilla; utilizando el ae Piss 4 ae aeieto <tilesinsert> indicaremos el nombre de la definicién Goition a aplicar a cada pagina. El siguiente listado indica como quedaria la i] de las pginas paginal.jsp y pagina2,jsp del ejemplo: emer paginal.jsp chapage content Type="text /html"*> ctepage pageEncoding="UTF-8"t> <t@ taglib urishttp: //struts.apache.org/tags-tites prefixe"tiles" %> «tiles:insert definition=".parapaginal"/> pagina2,jsp <4@page contentType="text/htm1"$> <¥@page pageEncoding="UTF-8"%> <¥@ taglib ur: tty ‘/struts.apache.org/tags-tiles prefix="tiles" %> <tiles:insert definition=".parapagina2"/> PRACTICA 7.1. APLICACION PARA EL ENVit VISUALIZACION DE MENSAJES oe Sasa: “ZAIN El evo aspecto de Iss Piginas deg a Bam 4 cain ot ue = ® —— col oe Fig.34. Paginas de laaplicacién Desarrollo n una pagina maestra (master.jsp) se crear la estructura _En r ctura de las piginas de la -aplicacién, Ja cual estara formada por una zona superior, un in lateral inquierdo y un cuerpo central. El mens serA comin a todas las paginas y estaré formado por una pigina {(menu.jsp) con los dos enlaces que se muestra ena figura. La zona super formada por un elemento de texto, mientras que el cuerpo seré ocupado por ISP que sera diferente para cada pagina. Tanto la pigina maesra como s de contenido se colocardn en un directorio interno en WEB-INF archivo tiles-defs.xml se indicarin las definiciones. Habré una ‘una para cada pfgina, De esta manera as referencia ala definicion a aplcar Listado 4 ee Mostraremos cnicamente las paginas JSP y los archivos dala puesto que las clases vontrolador y de negocio no suften ni Cong especto a la version presentada en la practica 5.2. ninguna ae struts-config.xml aa En fondo sombreado se muestran las modificaciones reali apuntar a las nuevas paginas, asi como los nuevos elementos ines Pe permitir Ia utilizacién de tiles: hidos pa ‘caxm) versions"1.0" encoding="UTE-8" 2 cipocryE struts-config PUBLIC »-//apache Software Foundation//DID Struts configuration 1.2//EN" snttp://jakarta.apache.org/strute/dtds/etrut; config_1_2.dta"> 8 estruts-config> <form-beans> ‘form-bean name="MensajeForm" type="javabeans -MensajeForm"/> </form-beans> <global-forwards> <forward name="previoenvio" forward name="previolectura" «forward name="inicio" -8.EnviarAction" > CAPO: . 2 </action> </action-mappings> _/struts-config> files-defs.xml coxml version="1.0" encodings: UTE-g* eIDOCTYPE tiles-definitions pustic *_//mpache Software Foundation//prp Eonflauration 1i/jme whttp: //jakarta.apache.org/struts/atds/t config_1_1.dta"> tas/tiles- <tiles-definitions> definition name=" principal path: /WEB-INF/plantillas/naster.jsp"> <put name="titulo™ value="aplicacién Web para envio y recepcién de mensajes"/> "menu" /WEB-INF/plantillas/menu.jsp <put name="cuerpo" value=""/> . </definition> definition name=". inicio" extends=".principal"> eput name="cuerpo" yalue=" /WEB-INF/plantillas /bodyinicio. jse"/> _ </definition> _ <definition nam titulo" value=’ “solicitua” extends=" principal'> spatos del destinatario"/> put name="cuerpo" dalues" /wap-INF/plantiias/bodysolicltis jap"l> ee ere 212_ STRUTS. cdetinition nanex*.envio" extendas"ipeinel daze cput nanee"titulo" values"Genezacién dy ¢ cput name="cuerpo” meneajegs), value=" /MEB-INP/plantillas/bodyenvio. 4, es </definition> cieeinivion names" muestra" extends="-principals cput nane="eitulo" value="Listado de meng bs eput name="cuerpo” ‘ajesn/, value=" /WEB-INF/plantillas/bodymuestra. 4 “Jepr/, </definition> wyefinition name=".nomensajes" extenda=" ‘put name="titulo" value="Aviso"/> “Datnctpai ts <put name="cuerpo" value="/WEB-INF/plantillas/bodynomensa$, </definition> es dant </tiles-definitions> Plantillas y paginas de contenido master.jsp <tepage content Type="text/html"*> c#epage pageEncoding="UTF-8"%> <49 taglib uri-http: //struts. apache. org/tags-tiles prefix="tiles" *> <4@ taglib uri="http: //struts.apache.o: : .org/tags-logic" prefix="logic" %> ees <%@ taglib uri-"http://struts.apache.org/tags-bean" prefixe"bean" > s «te taglib uri-"http: //struts.aj -apache.org/tags-html" prefix="htmi" $> sare oe eae "-//W3C//DTD BTML 4.01 ‘Transitional//EN" i <tiles:insert </td> z </table> </body> </heml :html> menu.jsp <#@page contentType="text/html"t> <sepage pageEncoding="UTF-a"t> <$@ taglib uri-h pre: //struts.apache.o1 html" &> <center> <br/><br/> <chtml:link forward="previcenvio"> Enviar mensaje </htm:1ink> <br/><br/> <html: link forwar¢ Leer mensajes </html:Link> </center> "previolectura"> ee ee 214_ STRUTS bodyinicio.jsP text/html" ¥> ctepage content TyPe= uTe-8"%> crapage pagezncoding= <center> or plemvanido « im @tceoteemee imam recepein de mensajes</h3> </center> bodyenvio,jsp etepage contest types" tet BENLiss caepage pageEncoding="OTF-8°t> ese tagiib urishbtp; //atrubs -apdehesGza/ tect) prefix=thtml" *> <center> <html: form action= <br/><br/> “bsDatos del mensaje:</b><br/><br/> "/grabax" method="POST"> <table> <tr> <tdoIntroduzca destinatario:</td> <td> chtml:text property="destino"/> </td> </tr> <tr> <tdoIntroduzca remitente:</td> <td> <chtml:text property="remite"/> te eed colepane"2" sch lt? </table> Gpneml form efeontex> </booy? podymuestra.jsp exepage content Type="text /hem ry Cyepage PageEncoding="Ury-ary, “xe page impor! xe taglib uri Javabeans.+, ja nttp: //struts.a prefix="logic" ¥5 i * NES. apache .org/y, T3/taga, <a taglib urishttp: //struts. ap, pache or prefix org/tag bean" %> Bypieesii wri-bttp: //etrace.apach prefix-"html" t> ree center> cbean:parameter id="nombre" nan <h3> Mensajes para <bean:write nane="norbre"/s </n3> ctable border="1"> <tr> <thoRemitente</th> <th>Mensaje</th> </tr> <logic:iterate id- mbre' /> mensaje" name="mensajes" aa. scope="request"> <tr> <td> ebean:write name="mensaje" ="remite"/> </ta> <td> <bean: write name="mensaje" property="texto" [> </td> erate> </logics it </table> br /><br/> a <html : Link forvard=" inicio" >Inicio</btml : Links z ae </center> bodysolicitud.jsp text/htmL"t> “UTF-8"%> <tepage contentType= <topage pagesncoding= «center> ebr/><br/> ccorm action="mostrar,do" method="post Introduzca su nombr' put typesttext" name="nonbre"><br><br> ngubmit" value="Mostrar mensajes"> <iny <input type= </form> </center> bodynomensajes.jsP <topage content Type="text /htm1"&> <t@page pageEncoding="UTF-8"*> <4@ page import="javabeans.*,java-util.+"#> <t@ taglib urishttp://struts.apache -org/tags-bean prefix="bean" ¥> 3 <t@ taglib uriethttp; //struts-apache.org/tag: prefix"html" %> : paginainicio.jsP “exepage CONCENETYPE="Lext /htmi ny Stepage PASENCOGINGS"UTE-gny, Ae taghib uricbttp: //strute. ep prefix="tiles" 4, Pache, eqiles:insert definitions»; paginaenvio.isp “eopage content Type="text /hemiy, “sepage pageEncoding="UTP- any, ise tagiib uri-http://strots.apa prefix="tiles" > . Upiles:insert definition=" envion cheor paginamuestra.jsp “sepage contentType-"text /htmi"t> esepage pageEncoding="UTF-s"¥> ese taglib uri-http://struts.apache.org, prefix="tiles" %> Ceiles:insert definition-".mestra*/> paginasolicitud.jsp ‘ekgpage contentType="text/html"t> ahepace ipagezacodin UTE-8"%> ‘tp: //struts.apache.org/tags- tiles" %> =" solicitud*/> age pageEncoding: NUTF-8"%> aglib uri-http: //struts apache ord | prefix="tiles" msert definition=" .nonensajes"/> eags-tiles Capitulo g SS? Las cada vez mis exigentes demandas de las a pa leado al eo de desarrollo de Struts, en su = ey Web moderas faciones del framework, a replantear la estustim mma ses ‘ : Bs H™ adopiando un nuevo enfoque que resulte mis ate Y composicién, det nesta linea nace Struts 2. ley sencillo de utilizar Mas que una nueva version de Struts, Struts 2 syorks: spor un lado el clisico Strus ee comets grr tiie 1) con nuevas capacidades afadias, y por oo VaWon Gaseee say la versionactualizada ymejorada de x), un fancwa da = por OpenSymphony que proporciona un fuerte desacoplamiento entre es 2 Inaplicacion. Fl resultado es un producto que integra las capacidades de ambos fnmeworks, lo que sin duda hace de Struts 2 el marco de trabajo mis atractivo y pent paa la creaci6n de aplicaciones Web con arquitectura MVC. i ee ‘Lo anterior no significa que Struts | haya entrado en vias de desaparicion, ho menos. Struts 1 es un framework muy consolidado, integrado en la a de los entornos de desarrollo més importantes y utilizado por una comunidad de desarrolladores, mientras que Struts 2 tiene que madurar bien tiene un gran futuro por delante. a 8.1 COMPONENTES DE STRUTS 2 7 jecimos, Struts 2 sigue siendo fiel a la arquitectura Myo. Como dernan algunos de los componentes tradicionales carat asempefian roles que desempefi ot respecto a las versiones 1x a figura 35 muestra los principales componentes de Struts 2, gy yp sero de os dsinas capas de Ia aplicaciony la interaccién entre os ign dentro de las distint Controlador Modelo | Interceptors: a -_ Fig.35. Componentes y capas de una aplicacién Struts 2 A continuacién estudiaremos el funcionamiento y principales caracteristicas de estos componentes, analizando su comportamiento a lo largo del ciclo de vida de la peticién desde que ésta llega al Controlador hasta que se envia la Tespuesta al cliente. 8.1.1 FilterDispatcher __ _ Este componente representa el punto de entrada a la aplicacién, dirigiéndose a él todas las peticiones que Megan desde el cliente. FilterDispatcher hhace en Struts 2 las veces de ActionServiet en Struts 1, analizando Ia peticién y determinando con el a poy; 2 almacenada en el archivo de ort, ° objetg Y “onfiguracis OS uni, macion stu. male ting de rilterDispatcher forma parte del ap del paquete org.apache struts) die SMS 2, cop, es implementado mediante un flee: Om jbb:xmil de la aplicacion tal y como -.°%, © We de c dentto pombres chi $.1.2 Interceptores Una vez determinada la accién a ejecutay, FlterDispatcher p dela peticion a un objeto intermediario de tipo ActonProxy,éxe crea un sbi Mefioninvocation en el que almacena la informacién de a peicién enrae pexandoacontinuacién el contol delamismaalosinerceoes. tral Los interceptores constituyen una cadena de objetos que realizan una serie de tareas de pre-procesamiento previas antes de ejecutar la accién, como por gemplo la validacién de datos de usuario, rellenado de objetes con ls campos de {in formulario, etc., asi como un post-procesamiento de los resultados una vez que &tos han sido generados por las clases de accion. ___ El funcionamiento de los interceptores es muy similar alos filtros servlet, “sleeutindose en cadena al recibir la peticion, en el orden indieado es al archivo de i6n struts.xml y en orden inverso durante el envio de la respuesta al 22 STRUTS corpora un gran ndmero de interceptores, EI API de Struts incorpor > de in Be ‘teciais el programacdoc collenside tO) = a iam Pig, serie vmente indioandolo- en el McMnve We CAC aes ae a simp! ores proporcionan a las clases de accién acceso a log tn - estos interc rc i oa d e Peri de que éstas puedan controlar 10s datos mane, "i objetos del API Servlet, Ia aplicacion emos mas adelante, un oe también puede impt ae para realizar algin tipo de pre-procesamienty sus propios interceptores pari an : ; ee age personalizado que no esté contemplado por nin; intereeptores del API. Para este propésito Struts 2 proporcion; Como vé st. UNO de py 1 1a interfay 8.1.3 Action Como sucede en Struts 1, Jos objetos Action se encargan del procesamien, de las peticiones del cliente. Sin embargo en Struts eae de objetos Present we ables diferencias respecto a las versiones anteriores; analizaremos lag mys 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 sucedia en Struts 1.x, jg Iogica de negocio se suele aislar en clases independientes o EjR incluyéndose en las clases de acci6n las lamadas a los métodog expuestos por estos objetos. = Implementacién como clases POJO. La principal caracteristica de las clases de accién de Struts 2 es que no tienen que heredar ni implementar ninguna clase o interfaz del API. Son clases estandares Java, comiinmente conocidas también como Plain Old Java Objects (POJO) y cuyo nico requerimiento es tener que proporcionar un método, que por convenio es llamado execute() al igual que las clases de acci6n utilizadas en versiones anteriores del framework, en el que se deberan incluir las instrucciones a ejecutar para el procesamiento de la accién. Este método sera invocado por el tiltimo interceptor de la cadena. * Inclusion de métodos set/get. Otra de las caracteristicas de Struls 2 es que se ha eliminado la utilizacién de clases de tipo ActionForm para la encapsulacién de datos procedentes de un formulario cliente. En su defecto, estos datos son capturados por el propio objeto de spun incluidos en el API d 8 programador. Lo ince, tt 2 eats? og oe, MICO que en este tO asi mere Jas clases de accién agcn.°% Snide poem rf ete F Tabré que Para tratamiento de la peticiny ss Méodg =. Stee almacenamiento de los cam, Sean og tae errewtey tans a el set/get, de forma similar a ee Tem ilar sus ae de Struts 1. @ como se 5 Pn a Este nuevo sistema Ia aplicacién, ya que por Plea dy : + Y8. qUE Por un ladg ar “Oblemente ag distintos de clases a implememes “Ue l nim lesarollo de directamente de los datos en je manipulados. la misma clase En caso de que queramos encapsular lo facilitar su transporte entre las clases Agi tS par que encapsulan la légica de peyeig 18 sompe 9.1.4 Librerias de acciones Como en Struts 1, Struts 2 incluye un amplio conjunto de ac que fvlitn Ta creacién de las visas. Estas aciones se iteluen enn ino uriasociada “/struts-tags”. y la libreria de Como novedad respecto a las versiones anteriores, estas acciones pu ifilizarse no solo en la construccién de paginas JSP, también con otras tenologias jaralla creacion de vistas como son las plantilas velocity ofeemaker ‘Ademés de incluir una gran variedad de componentes grificos y elementos “de control de flujo, esta libreria proporciona acciones que permiten acceder directamente desde la vista a la accion que se acaba de ejecutar, facilitindose ‘siel acceso a los datos generados por el modelo. Archivo de configuracién struts.xml Las aplicaciones Struts 2 utilizan un archivo de configuracién aa aml en el que se registran y configuran los distintos ‘componentes cP tealizdndose estas tareas de una manera mas simple que en st Shy, 2 soporta ademas la herencia de archivos de configura, ett? Sar car una serie de configtraciones por det © se raduce on Power que reescebirlas de nuevo en cada struts.xnl parjeyp, ly aplicaciones sin ter : sa figura 36 nos muestra Ia estructura bésica de un archivo struts vchoro ‘itt wsigir en un directorio que esté incluido en el clasypoyt Ee fichero derrabitualmente raz, aplicacion\WEB-INF\classes, ae aplicacién, habitua <?xml version="1.0" encoding="UT F-8" 2> <!DOCTYPE struts PUBLIC f iApache Software Foundation/DTD Struts Configuration 2:0//8N" stttp//struts.apache.org/dtds/struts-2.0.dtd"> struts <package ...> <interceptors> efinicién de interceptores personalizados-—> <finterceptors> <action ..> <!--configuracién de elementos para la accién—> </action> </package> </struts> Fig. 36. Archivo de configuracién struts.xml 8.1.5.1 PAQUETES Cada configuracién 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 configuracién comunes. Un elemento <package> puede incluir los siguientes atributos: "name. Nombre o identificador asociado y que debe ser tinico part cada paquete. un Mapeg ha asignado el valor -mesPace em ‘ acciones definidas "eSK™@mple™ jy raiz_aplicacion’ \Packexample et no ejemplo, si al atribun interior = extends. N Pan acti » Nombre del pagu 5 anteriormente, Struts Jt heredady configuracién, concretamene tt, her its a bere ls herencia de p, 4152 HERENCIA DE PAQUET; % Struts 2 proporciona un archivo ge ss-default.aml, en el que se incluye y iquiet aplicaciOn. Entre otras cosas, egy Pon rereeptores predefinidos de Strus 2 SSte ‘paque Configuracion por q res a fant com se con Ulilizndas - POF To que ei qe Une serie jonalidad de Tos mismos en nuestra aplicacig se °° disper dey .den a éste: } Serd Conveniente crear areas que here ‘Tear paquetes package name namespa extends="struts-defaults, </package> A modo de ejemplo, en el siguiente listad 5 sa stado se mu ee auchivo de configuracién por defecto de Strus 2 strut eed a encuentra incluido en la libreria struts2-core-2.0.11 jar suministrada con 2 —— de distribucion de Struts 2: con el paguete Wend version="1.0" encoding="UTF-e" 2> Sid: struts-default.xml 559615 2007 hk eensed to the Apache Software Founda ae More contributor license agreements Waistributed with this work for additional in garding copyright ownership. The ASP licenses this file © you under the Apache License, Version 2.0 (the Miicense"); you may not use this file except in compliance HEH the License. You may obtain a copy of the License at Attp: //www.apache -org/licenses/LICENSE-2.0 " 5 i writing, ‘requived by applicable law or agreed to 39 Wet distributed under the License is dist 226 _STRUI -THOUT + nas 19" BASIS, WITHOUT WARRANTIES OR CONDITE ‘S15, press or implied. | Ou OF 7 KIND, either cme governing permissions and limitat{ons"® + thder the License. */ 0 ute PUBLIC coer set EE» nanon/ fo Beran Golem 2.0//EN" | j/etruts-apache.org/dtds/struts-2.0.dtdr> <stryrean class="com.opensymphony .xwork2.ObjectFactory« See ee work2 . Object Fact bean type="com, opensymphony . 2 ‘actory” names classe org apache. strute2.impl.StrutsObjectFactory" /s "=~" Struts, ebean type= "com. opensymphony .xwOrk2 . Act ionProxyFactorys name="xwork" class="com. opel <bean typi name="struts" ‘ ¢ diaso~"org. apache. struts2. imp] .StrutsActionProxyFactoryn/, nsymphony . xwork2. DefaultActionProxyFactoryn/. com. opensymphony . Xwork2 . ActionProxyPactorya <bean type="com. opensymphony..xwork2.util. Object TypeDeterminery name="tiger" 5 . f class="com.opensymphony .xwork2 .util.GenericsObject TypeDeterminers <bean type="com.opensymphony .xwork2 util. ObjectTypeDetermiae,” name="notiger"™ ; ss class="com. opensymphony .xvork2 .util .DefaultObj ect Typepeterminert <bean type="com.opensymphony. xwork2util.ObjectTypeDeterming.s name="struts" ; x class= "com. opensymphony .xwork2.util.DefaultObjectTypeDeterminern/, <bean type="org. apache. struts2.dispatcher.mapper.ActionMappers name="struts" class= "org. apache. struts?.dispatcher .mapper.DefaultActionMapper" / <bean type="org.apache.struts2.dispatcher.mapper .Act ionMapper* name="composite" class="org.apache. struts2. dispatcher mapper . CompositeActionMappers P <bean type="org.apache.struts2.dispatcher. Acti " soe spat cher .mapper .Act ionMapper: class="org.apache.struts2.dispatcher.mapper.RestfwlActionMapper" /> <bean type-"org. apache. struts2.dispatcher.mapper.ActionMapper" ‘org. apache. struts2.dispatcher.mapper .Restful2ActionMapper" I> tipart .JakartamultiPartReqe — an tyPe="0FS- apache atr,, cag apache. strute: ite oo TUES2 Views pe; an beats .apache. struts? vi, 288s sprate” optional="truers) © jan cla8S="0rg. apache Bere eae optional eee tite sale’ bean forg-apache.strui quasen"Org- AP! 82 component, P spean beet apache.struts2.c eypeceftl" 92025 _torg-aPache Struts? compon, pas we eitorg- apache. Struts2. conpone : opened ES Cong ganeecrorg-apache.strute2 component, «, ¢ <bean "org.apache .struts2 ne=" 18D" sigss-"org apache. struts2. components components bean Eype="com. opensymphom Sexwork" class="com.opensy: cbean type="Com.opensymph panes"struts" Glase="com.opensymphony..xvork2 util .annota iebean’ type="Com. opensymphony. works ren oeeMOERCom @lase= "com. opensymphony .xwork2. TextProyiqe ioe <bean type="Ccom.opensymphony.. xvork? soe @lass="com. opensymphony . xwork2.. TextProvia XWorkconye dersupport™ I-- Only have static injections --» <bean class="com.opensymphony . xwork2 0b} static="true" /> “<bean class="com.opensymphony.xwork2.util statice"true" /> of: <bean class. statice"true" /> bean Class="org. apache. struts2.dispatcher.Dispatcher* eget Bi patcher Dispatcher "<bean class="org.apache.struts2.components. Include" ‘Static="true" /> | sbean class="org.apache.struts2.dispatcher. Filter! XviorkConverter* ‘Com. opensymphony. xwork2 util cgnlValuestack"™ }ispatcher* sbean Class="org. apache. struts2.views.util.ContextUtil" "true" /> Class="org.apache.struts2.views.util.UrlHelper" true" /> <. cpenuyuphorly wrk? -REtiOnCiesomGgaae ge "CO peep wdiepatcher” “type name= apache. struts? dispatcher ServietDispatcherResult. 10112 ve type manent Ereemarker! ‘TN Grosult-CYPe "lene, Freonarker -Preenarke! f class-"org-apache Ot type name="httpheadert Result), apache. strutez dispatcher .HttpHeaderResult™/> patuit-type namex "redirect ” a"org totyPe2 dispatcher .ServietRedirectResult/ class=torg.-apache: StEv" 0? anes” redirectAction" : NezesultCYPe "dtepatchor. Servl@eactsonRedirecthag aan rorg.epeeba scr ee? dlapse cher, SUreaRRaaule/= ‘<result-type name="velocity" class<"org.apache.struts2 ‘dispatcher. VelocityResult"/> PC eg names xe1e serena Os eleva role. XSLTResult*/> pache, Struce?. Tmew"plainText class-"org. apache. struts2 ‘dispatcher .PlainTextResult" /> pache Sprecated name form scheduled for removal 4 jclangbeprecates Versions aze preferred. See wi-179 the, cane! Cananes"redizect-action" 7 class="org apache .struta2. dispatcher -SeryletActionRedirectResuit» Presuit-type name="plaintext" ies rorg.apache-strute2.dispatcher.PlainTextResult" /> </result-types> class-"0rg- terre org. clasi class="org struts 2.1 class= <interceptors> ‘<interceptor name-"alias" com.opensymphony .xwork2.interceptor-AliasInterceptor"/> cinterceptor name="autowiring" class="com.opensymphony -xwork2. spring. interceptor .ActionAutowiri terceptor"/> ae ‘interceptor name="chain" class="com.opensymphony .xwork2. interceptor .ChainingInterceptor"/> interceptor name="conversionError" org. apache. struts2. interceptor. StrutsConversionErrorintercept clas: <interceptor name="cookie" class="org.apache. struts2, interceptor .CookieInterceptor"/> |, _cintezceptor nane="createsession* class-"org.apache. struts2. interceptor .CreateSessionInterceptor" /> 1, ,cinterceptor name= "debugging" ee lorg.apache . struts2. interceptor . debugging . DebuggingInterceptor ag aes eereep rine i osternatie’ eineee tere -opensymphony .xwork2. interceptor . ExternalReferencesinterce <interceptor name="execAndWait" truts2. interceptor .ExecuteAndWaitInterceptor"/> o ‘ion! ee ceptor. ExceptionMappingIntercept einterceptor nane-*} opensymphony - xwork2 , ¢.79°"" oO ORG ntercept ase winterceptor nane-s acom.OpensYMPRONY .2WOrK2 Teeg eet ven user Tinterceptor namen*scseTSePt : get com- OBEnSYMPHORY -2000rks es aei> Di reeemrtor memes pa -ecom-Opensymphony -xwOrk2. interes ass" CANEEXCEPtOr namentpreecee™ gqrcom. openSYMPHONY -xWOrK2.intercer ase cinterceptor name-wsrce wcom.opensymphony . xwork2.interce ase ol? <interceptor nane="scope e*org-apache. struts2. intercepts class tinterceptor name-"serve gusnvorg-apache-SErute2. intercepeor clas tinterceptor name="seseig setorg.apache.struts2. spring. i exceptor”/> gat <interceptor nam 2 ncom.opensymphony . xwor! <interceptor nam g-torg-apache.struts2. in a <interceptor name="tokense, clase" ge <intexceptor name="validation" Qussstorg apache. struts2. interceptor. valia p Lidation Gintezceptox"/> cinterceptor name-"workflow" iaes-"com. opensymphony .xwork2. interceptor.pet ae <interceptor name="store" (ase="org. apache. struts?. interceptor Messagestor: ; <interceptor name="checkbox" Gsses"org.apache .struts2.interceptor.Checkboxinterceptor" /> ; ‘interceptor name="profiling" ‘Glase-"org. apache. struts2. interceptor. Pro <interceptor name="roles" org apache. struts2.interceptor.Rolesinterceptor" /> | <!-- Basic stack --> <interceptor-stack name="basicStack"> <interceptor-ref nam "exception"/> <interceptor-ref name="servietConfig"/> cinterceptor-ref name="prepare"/> cinterceptor-ref name="checkbox"/> <interceptor-ref name="parans"/> : <interceptor-ref name="conversionError’ b </interceptor-stack> <l-- Sample validation and workflow stack © 4, “Einterceptor-stack ‘nam fval idationvorkflowstack Sinterceptor-xef name="basicsteck > ‘interceptor-ref name="validattor”! Sinterceptor-xef name="workslow that intercept parameters as a DAO object loading in the interceptor to </interceptor-stack> so uploed seas 154 Stghe Ce naen eNO aeea <intercePtceptor-ref name="fileUpload"/s Entercer ret paeen ae eee finterceptor-ref name="basicStack"/> ample action chaining stack --> S{ntertebtor-stack names chainstack"s SS Gnterceptor-ref name="chain"/> Sinterceptor-ref name="basicStack"/» </interceptor-stack> <!-- Sample ii8n stack --> nterceptor-tack name "i2@nStack"> " cinterceptor-ref name="i16n"/> nterceptor-ref name="basicStack"/> </interceptor-stack> <I-- An example of the parans-prepare-params trick, hi, is exactly the same as the defaultstack, except includes one extra interceptor before the prepare the params interceptor. directly to an object that you wish to load externally (such S useful for when you wish to apply or database or service layer), but can't load that until at least the ID parameter has been loaded. By the parameters twice, you can retrieve the object Prepare() method, allowing the second parans apply the values on the object. --> <interceptor-stack name= "paramsPrepareParamsStack"> <interceptor-ref name="exception"/> <interceptor-ref alias" /> <interceptor-ref '‘params"/> <interceptor-ref name=", servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> sinterceptor-ref name="checkbox"/> sinterceptor-ref name="stat icParams"/> <interceptor-re¢ <interceptor-ref <interceptor- <paran nods*>input back, </interceptor-rets *"</Pare <interceptor-ret “ ‘<param PICS jethods">input , back, c: </interceptor-refs "°°!</Paran, </interceptor-stacks A complete stack with 21 the 3 — Generally, E This stack should be th the one you Peeege oe FRAN You need, Ats0, tn, ie switched around (ex: £ you wish to have yo Beeson PPD be Pore prevare() i, 1. move esd tO Serviet-config interceptor up pete Peacke 2120 Excluies: tron the no, the normal the method names input, back, a + back, and cancel associated with requests that shou > <intexceptor-stack name="defaultstack"» <interceptor-ref nane="exception" /. <interceptor-ref name-"alias"/> <interceptor-ref nane-"servletconfig"/> <interceptor-ref name="prepare"/» <interceptor-ref name="ilgn" <interceptor-ret <interceptor-ref name-"debuaging"/> <interceptor-ref name="profiling"/> <interceptor-ref "scopedNodelDriven"/> <interceptor-ref modelDriven"/> <interceptor-ref fileUpload <interceptor-ref checkbox" /> <interceptor-ref "staticParams"/> <interceptor-ref name="parans"> <param name="excludeParams">dojo\ ..*</paran> </interceptor-ret> <interceptor-ref name="conversionzrror"/> <interceptor-ref name="validation"> <param UdeMethods">input, back, cancel, browse</param> _ </interceptor-ref> ___ <interceptor-ref name="workflow"> ee thods">input , back, cancel, browse</param> _,_</interceptor-ref> erceptor-stack> » completestack is here for backwaras See ‘applications that still refer to the detaurese compat db by the old name -~> erceptor-stack name="completeStack=, <inrtineerceptor-ref name~"defaultStacke/» </interceptor:FERGE: Sample execute and wait stack. Notes execandNaie SHOWIC alwage ie the *last* interceptor. --2 erceptor-stack name="executeAndWaitstackn, “in\tinterceptor-ref name-"execAndWaites " eparam name="excludeMethods* > nput , back, cancel</param> </interceptor-ref> <interceptor-ref name: "defaultstack"/s tor-ref name="execAndWait <param name="excludeMethods"> input , back, cancel</param> ref> d name forms scheduled for re, The camelcase versions are preferred. See ww-1707 --» eptor name="external-ref" "com. opensymphony . xwork2. terceptor . ExternalReferences eptor name="model-driven" com. opensymphony .xwork2 nterceptor .ModelDrivenint, me="static-params" class="com.opensymphony .xwork2. interceptor .StaticParametersInterceptor <interceptor "scoped-model-driven" class= "com. opensymphony .xwork2 nterceptor . ScopedModelDriv. <interceptor name="servlet-config™ class="org. apache. struts2 interceptor. Servlet Config: <interceptor name="token-session™ moval in Interceptorn/, erceptor'/, > renInterceptor"/> Interceptor"/> clags-"org. apache. struts2. interceptor TokenSessionStoreInterceptor"/ </Anterceptors> <default: ~interceptor-ref name="defaultStack"/> </package> </struts> oonee estos archivos mediante el elements, < jgrutta relativa del archivo a inch, ME, ef Sua indie Bh en *s atthe 5 B siguiente ciemplo dstibye geohivos xml, incluyendo cada ung 9°? “Mfigurac en iaaplicacion: mo de ellos a config Ia <strute> Cada archivo incluido tendré ex cualquier archivo de configur; ‘actament e acion struts xm ‘misma cstructrs g 8.2 BENEFICIOS DEL Uso DE STRUTS 2 Del analisis que hemos ido realizando sobn framework se deducen ya algunos de fi programadores de aplicaciones Web. A continuacic caracteristicas clave que aporta este nuevo framework. evo framework componentes los beneficios que s = Acciones de tipo POJO. La posibilidad de para implementar las acciones reduce la complefidad del des de las mismas y permite un desacoplamiento entre capas, utilizar clases simples = Eliminacién de ActionForms. Las clases de accién p disponer de propiedades para almacenar los datos de haciendo innecesario el empleo de un nuevo tipo de clase adicional. " Variedad de resultados. La posiilidad de utilizar distints tecnologias para la generacién de una vista en aplicaciones Struss 2, tales como JSP, velocity o freemaker, proporciona una gran flexibilidad en el disefio de las mismas y offece un gran variedad de posibilidades a los desarrolladores. niimero de _acciones y las capacidades de es anteriores del = Amplia libreria de acciones. El personalizadas para la generacién de la vista éstas han aumentado respecto a versio framework. 2 kk Posibilidad de utilizar anotaciones. Como ith ficheros XML, Struts 2 soporta ‘el uso de anotaciones ah cronies parimetros de configuracién en las acei, ca tgmplejidad de la aplicacion. iones, me iciones por defecto. La posibilidad de Onna de configuracién predefinias® = me setymemente la labor del desarrollador, ise 7 ¢ para AJAX. La utilizacion de ATAX en of g Sonne para Web ha supuesto una enorme reduasatollo i e las_mismas, mejor; mg mpo de respuesta de s, mejor poaeee de los usuarios con la interfaz grificg 48 iy proporciona una serie de tags que permiten aftadir capaci AJAX a las aplicaciones. ie 8.3 CREACION DE UNA APLICACION DE EJEMPLo be STRUTS 2 Seguidamente se va a explicar e6mo crear una sencilla apticacién Web de ejemplo con Struts 2, la eual nos servird para conocer el funcionamiene & famework y aprender a crear y configurar los elementos principales, La construccién de Ia aplicacién puede realizarse de forma many ° uilzando algin IDE. En el momento de escribir este libro (febrero de 2008) a4 no existe ning entomo de desarrollo que incorpore algin plug-in, como ay 4 caso de Struts 1.x, que facili Ia construccién de aplicaciones con Struts 2, «ti, hay algunos proyectos en marcha para integrar Struts 2 en Eclipse y NetBeans que en poco tiempo veran la luz. 8.3.1 Descarga del paquete de distribucién de Struts 2 Lo primero que tenemos que hacer sera descargar a tltima version de Paguete de distribucién de Struts 2 desde la pAgina http:/struts.apache.ore2., Fste paquete de distribucién consiste en un archivo .zip en el que se incluyen es Iibreras con os distintos componentes del framework, documentacién del AP! y 'una serie de aplicaciones de ejemplo (figura 37), Contenido det pa ‘te de ditribuciin de Sirus } 8.3.2 Requerimientos Software Las aplicaciones Struts 2 puede © Pueden ejecutarse con se T adelante, siendo ademés necesario disponer las chelate Iva EE les Versiones Java/J2EE * Servlet API23 = JSP API 2.0 = Java5 8.3.3 Descripcién de la aplicacién eal set pulsado muestra una pagina con un mensaje de saludo y la hora del sistema (figura 38) Bienvenido a Struts 2 Fecha att Sa Jan20 19:19, ‘CET Deg 8.3.4 Estructura de directorios de la aplicacién Al tratarse de una aplicacién Web, la estructura de director serd la correspondiente a cualquier aplicacién J2EE. En este ne me Mista tener en cuenta que debemos inluir en el directorio WEB-INFlib de ig ene las librerias Struts 2 necesarias para el funcionamiento de la aplicacign, Pica minimo deben ser: commons-logging-1.0.4,jar, freemarker-2. agi ome 2.6.11 jar, struts2-core-2.0.1 1 jar y xwork-2.0.4.jar. Jar, ogn), Suponiendo que el directorio raiz de la aplicacién 10 tam “ejemplosaludo” y tenendo en cuenta que la inica clase de accion que van utilizar se llamaré Saludo, la estructura de directorios de la aplicacién quedara ee como se indica en la figura 39. 4 saad ict he, stladajop Fig.39. Estructura de directorios de una aplicacién biisica Struts ts onan Cuando se vaya a de re de algunos elem rch también en el WEB. incluyen en el paquete de disrte 5 Registro de Filters, Una vez defini el filtro ree web.xml. Al nicio de la ap! Patcher </web-app> 8.3.6 Implementacién de la clase de accién En este ejemplo crearemos una tinica clase de accidn, a la que como hemos Visto Ilamaremos Saludo, que sera invocada desde la pagina inicio htm! cuando se pulse sobre el enlace. El cédigo de esta clase se muestra en el siguiente listado: aoe STRUTS 107 java.util Dates package mejemp: ciass Saludo { fe static final String texto= npienvenido a Struts 2" vate String mensage; ring execute() throws Exception { : ) public this sage = mensage; public String getMensage() { return mensage etFechaHiora () public String getFechaHi { te () toString () ; } Como vemos se trata de una clase normal Java en la que hemos definid a método, que por convenio se Hamard siempre execute en todas las ela’ de aceiéa, donde se incluyen las insruciones asociadas a accién y que ag? ciemplo simplemente consistrin en almacenar un texto dentro de la propieny “mensaje” del objeto. Este método deberd devolver una eadena de caracters aid seré utilizada para determinar el resultado que deberd ser enviado al cliente Ademis de execute), nuestra clase de accién de ejemplo cuenta condo Propiedades: “mensaje”, que contiene un texto con el mensaje a mostrar al Usuario, ¥ “fechaHora”, que contiene la fecha y hora actual del sistema, Esta tiltime propiedad no necesita de ningim dato miembro para el almacenamiento de su vale mi, Por tanto, de un método de tipo set, puesto que el valor de la misma se determinaré en cada momento instanciando un objeto Date. 8.3.7 Registro de la clase de accion Las clases de acci6n deben ser registradas en strutsxml mediante el = mame. Ni URL de acceso a ett? ta acci uno de estos definiré en sy nombre que es utilizado que en el cuerpo del ele ™ atrIbutO name of Por las clases de MENLO Se indicara jg En nuestro ejemplo et 1 siguiente listado, donde el regu} <struts> <packag) </action> </package> </struts> 8.3.8 Pagina de inicio La pagina de inicio de la aplicacién es una ‘simple pagina XHTML con un enlace que apunta a la accién saludo: <!DOCTYPE HTML PUBLIC "-//w3¢//D7D HIM 4.0 ‘Transitional //EN"> <html> <head> <title>Bjemplo de Strute

Para entrar en Struts 2 pulse emer. 240 STRUTS ta"ejemplo/saludo.action"> Aqui, seguido del nombre de la accion eed namespace con Ja extensién .action. 8.3.9 Pagina de resultado La pagina de resultado es una pé ina JSP cuyo cédigo se Muestra en ¢| siguiente listado: "text/html; charset-UTF-g" 4, uts-tags" $5 essage"/> S:property valu: fechatiora"/> Esta pigina JSP tiene como misién mostrar al usuario el mensaje de saludo y Ia hora del sistema, datos que son obtenidos a partir de las propiedades “message” y “fechaHora” del objeto de accion, Mediante el tag de Struts 2 es posible acceder desde la pagina de resultados a cualquiera de las propiedades del objeto Action que se acaba de élecutar. Este tag dispone de un atributo llamado vale que contiene el nombre de 1s propiedad cuyo valor se quiere recuperar. 8.4 UTILIZACION DE INTERCEPTORES Como ya dijimos anteri i nuevo tipo de compone lormente, los interceptores son un tes incluidos en la arquitectura Struts 2 j ae ; ar que se ejecutan ant del procesamiento de una peticién Por parte de un objeto de accién. ee El API de Struts 2 inch = lye un gran ni ue podemos utilizar en cualquics ‘imero de interceptors Pe io etia do iar Se mess s alcscones Web seas cane . = decide a través de struts.xmi qu La utilizacion de interce ; ptores. en un sencillas tareas en el archivo de eo ae acién . K ores quiere: realizar do. nnfiguracién struts.xm fais = Declaracién del interceptor. = Asignacién del interceptor a la accién 8.4.1 Declaracién del interceptor Un interceptor se declara en el interior del elemento , el cual dispone de los siguientes atribur butos: * name. Nombre asignado al interceptor = class. Clase a la que pertenece el interceptor. El elemento debe estar situado directamente en el interior del elemento . Por ejemplo, el siguiente bloque declara el intr FileUploadInterceptor de Struts 2, utilizado para facilitar el acceso a los fi subidos al servidor desde el cliente: heros cla: a de interceptores para permit accién, En este case, vie componen él ‘También es posible declarar un grupo 0 Pil : bre una Ie licados en bloque sol s qui pede ser a sat ‘uno de los interceptores a eS eae ma_STRUTS Se Ta bloque mediante el clement erceptor-stack>. bloque a través del element ceptor-stack> dispone del atributo name as Mes, l ae bloque. En su interior se utilizaré un ele bie asignar un ’ f mento , los clemento: fl * i re >, siempre después de la declara © “be incluir en ¢ yr de de Ig, interceptores individuales. EI siguiente mplo declara dos interceptores y una pila de interceny, constituida por éstos: package Mediante el atributo name de se indicaré el nombre del interceptor que se quiere incluir en la pila, ‘También pueden incluirse dentro de una pila otras pilas existentes, en este aso el atributo name del elemento deberd hacer referencia al nombre del grupo a incluir. ._ Como podemos ver en el listado que se present en el apartado dedicadoa la introduccién de los interceptores, el archivo de configuracién strut incluye la declaracién de todos los interceptores del API de Struts 2, asi como lade ee 8.4.2 Asignacién de un intere, Un interceptor o de intercept un elemento wilizado ex ef n° he 8 8 Aion a ravi 4 aquisiramos asigna el grupo creado St itetior de te ejemplo: . Si observamos el contenido del archivo struts-default.xml presentado anteriormente, veremos que existe una asignacién por defecto del grupo de interceptores defaultStack: i que herede struts-default, El interceptor ServletConfigInterceptor trabaja conjuntamente con itn serie de interfaces que la clase de accién tendra que implementar para poder tens acceso a los distintos tipos de objetos. Estas interfaces son: A través d ServletContextAware. Proporciona acceso al objeto ServletContext. + ServletRequestAware. Proporciona acceso al objerp HttpServletRequest. * ServietResponseAware. Proporciona acceso al objeta HttpServletResponse. * PrincipalAware, Proporciona acceso a un objeto PrincipalProxy que permite obtener informacién relacionada con la seguridad, * ParameterAware. Proporciona acceso a todos los parimetros enviados en la petici6n. = RequestAware. Proporciona acceso a todas las variables de peticion. * SessionAware. Proporciona acceso a todas las variables de sesién. * ApplicationAware. Proporciona acceso a todas las variables de aplicacién, Todas ellas, salvo ServletContextAware que se encuentra en el paquete ore-apache.struts2.util, estan definidas en org.apache. struts2.interceptor. Estas interfaces pr nta el nombre del obj un nico méy ei etContextA ware ieee odo llamado ServletRequestAware declara el méioan eConec), iets Los métodos de estas interfa ' de las cuat ces reel oe ‘ tro primeras interfaces ij ben como parimetr objeto al que proporcionan acceso, mina Corsa de una coleccién de tipo Map con I indicado. " 0 un objeto, g #0, que en Tena qa Per rcament data 2 ls cunro restates se tate Darimeros exstentes en el taka es en el imbitc Por ejemplo, util Be cerca P - itilizando 1a interfaz Session, aoci probara la existencia de sionAware la siguiente generando un resultado diferente en cada caso. i 250 de sesin llamada “wer import import public c jables.get ("user" else{ return "error" } En esta otra clase de accign se utiliza la interfaz ServetContextAware pat acceder a una variable de aplicacién que eva Ia cuenta del niimero de veces que Se ha ejecutado la accién: import javax.serviet Jmport. org.apache.strute2. intercePtor public class Comprobaraction inpLeneitt sezvletcontextarare private Sexvietcontext context? By public void getserviet context (Servletcontext context this.context=context — public String execute(}{ Integer cont=(Integer) context, getattribute ("contador") , if (cont !=nul1) { //instrucci6n v&lida a partir qq //ava 5.0 cont++; else{ cont=1; } context .setattribute ("contador", cont) , return "done"; PRACTICA 8.1. VALIDACION DE USUARIOS Descripcion En esta préctica vamos a desarrollar el médul que hemos estado utilizando en algunas pricticas de c través de una pagina de login se solicitard al usuario su lo de validacién de usuarios apitulos anteriores, donde a identificador y password, ok isp ‘Usuario no validottit no registrade Fig. 40. Paginas de la aplicacién Para validar los implementaré las interface 'S OFg-apache struts). org.apache.struts2.ut -ServietContextAware I datos del usuario Utilizaremos una cla interceptor Ser, las cuales nos py *Context, res » Fespectivamente. Medi; Gatos enviados en la peticién as com 2 os € encuentran almacenados los Parametros Se de accién que letRequestAware y a los objetos HtpServietr, roporcionarin acceso, estos objetos podremos acceder alos parimettos de contexto en los que s conexién con la base de datos equest y Servlet objeto de accién a fin de que sean accesibles fie mente desde las péginas JSP de I vista, en las que se utilizaré el tag para recuperar ambos valores, Utilizaremos una clase adicional, empleada en practicas anteriores, para inclur la ldgica de validacin; de us Contra la base de datos. Esta clase se apoyard a su vez en una clave obtener las conexiones con la base de datos, muy similar a la clase GestionClientes uarios Datos para Listado A continuacién mostramos el cédi ig0 de los diferentes componentes que / forman la aplicacién. web.xml : driver c: jdbe: adenaCon odbe:telefonia {ilter-namerstruts2 ass>org.apache.struts2. 6n y las dos paginas ‘isma--> class=-"misclases.Validar"> /pages/ok.jsp “error">/pages/error.jsp Validar Package misclases; import org.apache.struts2_interceptor.*; asport org.apache.strute?.util.+; Amport javax.serviet herp. Datos package import java-sqi.** public class Datos { } GestionClientes package misclases; import java.sql.*; public class GestionClientes { ate string driver? eeavnce sexing cadenacony private 8 e public patos () { : patos (sering driver, String cadenacon) { public Datos (St Pur ehie.driversdriveri hig cadenacon=cadenacon? ; ion) { ublie Connection getconex Pur connection on=nulls ery 7 craso. forName (driver) newInstance() ; cnabrivervanager .getConnection (cadenacon) ; } catch (Exception e) { int StackTrace () 7 ) return ) public void cierraConexion (Connection cn) { exy[ if (cn! && Jon, isClosed()) { cn.close(); } catch (sgLException e) { e.printStackTrace (); Datos dt; public GestionClientes (String driver, String cadenacon) { dt=new Datos (driver, cadenacon) ; Public boolean validar(string user, string pwd) { } login.htm! Login ebr/>


Formulario de Autenticacién post"
ctrs
name: etr> 4g STRUTS ok. jsp « text /html"* seen F-8"8 ye pa ‘ crut * ie »-//W3C//D" 4.01 ml"$> Brt> prefix="s" uri="/struts-tags" %> E HTML PUBLIC *-//W3C//DTD HTML 4.01 Trai t al//EN" http: //www.w3 .org/TR/htm14/loose.dtd"> shead> stitle>Error
shl>Usuario no vélido!!!1 la combinacién ~ se:properey va ¥ value="pyds melo .4.4 Interceptores Personalizados Ademis de utilizar los incluidos en el nicleo de & puede crear Sus propios imterceptores perondlinne om asociadas para luego poderlos utilizar en ou constituye ademés una forma elegante de dis distintos componentes de la aplicacién uts, izados con sus pro Programador diferentes desarrollos, lo distribuir funcionalidades entr Los interceptores deben implementar la interfaz Interceptor el paquete com.opensymphony.xwotk2 interceptor y cuy . siguiente listado: pai inet fa definicién se mue: éste donde se deberan incluir las instrucciones que realicen las tareas asig interceptor. El método 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 implementacién por defecto de los métodos de esta interfaz, de modo que si no necesitamos codificar los métodos init) y destroy(), pedemes heredar esta clase y sobrescribir dnicamente el método iereept), en vex de implementar la interfaz. 8.4.4.1 EL METODO INTERCEPTO Como ya hemos indicado anteriormente, el _método ene St contener las instrucciones que realicen las acciones asociadas al interceptor. igual que el método execute”) de las clases de accién, inercer ele String que servird para determinar el resultado a procesar para gene! s del cliente. ede apreciar al examinar el formato del métodg, jy, Segiin se p jeto ActionInvocation, el cual nos rem, é arimetro un objeto : 5 i recibe como Ps peticiOn en curso ¥ Ja accién asociada a la misma ea informacion sobre Ta Tprogramdor podré acceder a los daton ag &™¥ los métodos de ete oie ntey establecer el estado de la accion antes x Pt esta cl 5 manipular Ia respu stodos mas importantes de ActionInvocati sea procesada. Entre los métodos ‘On tenemos. jon(). Devuelve una referencia al objeto de accion aso: i ee en curso. Utilizando este objeto el pro, #Sociady asignar valores a sus propiedades u obtener los valores nc git 8 de 6 través de los métodos set/get. stas¢ getlnvocationContext(). Este método devuelve una refereneg al objeto ActionContext que proporciona acceso al_ context! aplicacién. Utilizando por ejemplo el método get) de este Objeto podemos recuperar una referencia a los distintos Objetos de} contexto de la aplicacién, como request, response 0 session, gt los principales métodos de ActionContext tenemos: get(Object clave). Como hemos indicado, este méiady permite obtener una referencia a cualquiera de los objee del contexto de aplicacién, recibiendo como Parametro I 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 método get() de ActionContext, como por ejemplo la constante HTTP_REQUEST que permitiria recuperar el objeto HttpServletRequest o la constante HTTP_RESPONSE que serviria para obtener una referencia a HttpServletResponse: public String intercept ( ActionInvocation invocation) { ActionContext context= invocation.getInvocationContext (); //referencia al objeto HttpServletRequest HttpServletRequest requ: (ttpServletRequest) context .get (HTTP_REQUEST): inter j a el valor del ep) leberiamos escribir eae getSession(). Devuelve un 1a coleccion Map variables de sesidn. con todas las getApplication(). Devuelve una coleccién Map con todas las variables de aplicacién. t invoke(). Después de realizar todas las op deberd pasar el control de la aplicacién al si en caso de tratarse del iltimo elemento de invocar al objeto de accién correspondiente. Esta operacién se lleva a cabo Mamando al método invoke) de Actionlnvocation, cuyo valor de devolucién representaré la cadena asociada en struts.xml al resultado que se debe procesar como respuesta. Es por ello que este valor debera ser utilizado como valor de retomo del método intercept(): jones el interceptor nte interceptor 0, la cadena, public String intercept(ActionInvocation invocation); return invocation.invoke(); 256_STRUTS_ ‘A 8.2, DETECCION DE USUARIOS HABITUALRS pRACTIC. Deseripcion La siguiente prictica que vamos & realizar consistira en un usuario it a es habitual del sitio, es Peseta aplieacion que sen capaz de detec © oes cain que St yeroridad, en cuyo c@30 86 Ie diigirh o ima pagina Go ada que le mostraré un ‘mensaje indicdndole esta circunstancia, personali usuario no ha visitado nunca el sitio se le levaré a una papi Nombre de usuario que sitva para recorda Pégina en ‘al sitio. La imagen de la figura 41 ais durante as Si que deberd introducir un isita que realice préxima v pégina involucradas distintas en la aplicacién. bienvenida jsp camprobr at Fig. 41. Paginas de la aplicacién Desarrollo Para recordar a | i Barents a los usuarios la aplicacién utilizaré i ae : Ish oA ne cae 4 eae introducido en la pagina de Be ras oe cai aaniens pcos een comprobara la eigeaid a Je acid si seta : fie fcieal aren 8 ita de un usuario habitual (true) o de EO eae i ae false). Una segunda accién llamada“ Jos usuarios que entran por primera ciate plcaciene Tt & crear Ia cookie para Listado Seguidamente se . Presenta el 6 forman esta aplicacién. Cédigo de tos distintos componentes we struts.xml eresult name="si">/pages/ok.jep/pages/login.htm! /result> "compruebauser"/> <{--accién asociada a la peticién grabar.action generada desde 1a pégina login.hts action name="grabar" class= migclases.GrabarAction"> result name="grabado"> Jpages/bienvenida.jsP 58 STRU UserInterceptor package misclases; import com.opensymphony. xWork2.*7 ‘port com.opensymphony .xwork2. interceptor. *; import org.apache.struts2.*; import org.apache.struts2.interceptor.*; import org apache. struts2.util.*; import javax.servlet .nttp.*7 import javax.serviet.*7 //elase correspondiente al interceptor personalizado public clase UserInterceptor extends AbstractInterceptor implements StrutsStatics{ public String intercept (ActionInvocation invocation) throws Exception { comprobarAetion action (Comprobaraction) invocation.getaction() ; //la interfaz StrutsStatics contiene una serie de //constantes que pueden ser utilizadas por el métogo //get() de ActionContext para obtener los distintos //objetos del contexto de la aplicacién ActionContext context= invocation.getInvocationContext () ; HttpServletRequest request= (HttpServletRequest) context .get (HTTP_REQUEST) ; Cookie [] cookies-request .getCookies () ; if (cookies != null) { for (int i=0; ic cookies. 1lengt! if (cookies [i] .getName() .equals ("user") ) { action.setExiste (true) ; action. setUser (cookies [i] .getValue()); itt) { } return invocation. invoke() ; } ComprobarAction package misclases import org.apache. st truts2, 4 import org-apache. struts2 4 import javax.serviet i... import ae public class Comprobara, public voi this. } public boolean getExi rei public void setExiste (boolean existe) { this.existe-existe; mn existe; } GrabarAction package misclases; import org.apache.strute2.interceptor.*i import org.apache.struts2-util.*; import javax.servlet .http. import javax.serviet.*i public class GrabarAction implements Servié gtring user; HttpServletResponse response; : public string execute() throws Exception { //genera 1a cookie para recordar al usuario : Cookie ckanew Cookie ("user",user) 7 Sa ee ck. wetMaxage (2000) ; are response .addcookie (ck) + return "grabado"; ) public string getUser(){ return user; public void setServletRequest ( HetpServletRequest request) { user=request .getParameter ("username") ; public void setServletResponse( HttpServletResponse response) { this.response=response; ) } Jogin.html



CarAD 8 on
bienvenida.jsp <4@page contentType="text/html"¥> <4@page pageEncoding="UTF-8"%> <¥@ taglib prefixe"s" uri«"/struts-tage" > ‘etitle»Bienvenida
chiosr./a. cBsProperty yaluestuser"/> 22_ STRUTS a usted ya ha estado aqui El conjunto de acciones JSP proporcionadas por Struts 2 puede dividirse en tres grandes grupos = Acciones de manipulacién de datos. En este grupo de incluyen todas las acciones para la manipulacién y extraccién de datos de aplicacion, como el acceso a las propiedades de un objeto Action o el establecimiento de valores en variables JSP. * Acciones de control. Incluye las utilizadas para el control del flujo de Ja aplicacién. * Acciones UI. Incluye acciones para la generacién de controles sréficos en formularios XHTML. Estos componentes encapsulan ademas toda la funcionalidad necesaria para que 10s. 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 atenderd la peticién, 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 y comprender su funcionamiento, ya que la mayoria de los tags de Struts 2 realizan un acceso al mismo para llevar a cabo su misién. value del tag property Los atributos value de las acciones Struts 2 también admiten expresiones. Estas deben incluirse encerradas entre los simbolos “%{” y “) 8.5.2 Acciones de manipulacién de datos Seguidamente pasaremos a analizar las princi incluyen en este grupo. 8.5.2.1 BEAN Realiza la instanciacién de una clase de tipo J - soportados por esta accién son: pales acciones que se JavaBean. Los atributos a 266 STRUTS + name. Nombre cuslificado de la clase que se va a instance . ficador de la variable donde se almacenaré Iq ; id, Identifix Telerenig a instancia. 2 PARAM i ss ros tags, como por gj Se utiliza para establecer parimetros en otros re eee Rode de un JavaBean creado con la accién . Media: pip pis Mento a 0 es " fame se indica el nombre del parmetro, incluyendo en el cuerpo det ¢) valor que se quiere asignar. 7 jones de ejemplo crearfa una instanci EI siguiente bloque de acciones « : una instancia det Mensaje y le asignaria valores a sus propiedades remite, destinatario y texto, bean avabeans Mensaje" id="mensa"> profe hola 8.5.2.3 PROPERTY Recupera el valor de una determinada propiedad. Su principal atributo eg value, el cual, como hemos visto anteriormente, debe contener el nombre de |g Propiedad que se quiere recuperar. El elemento es aplicado sobre los objetos del stack, empezando desde el mas externo hasta el mas interno, 8.5.2.4 PUSH Este elemento afiade un determinado objeto al stack. Mediante su atributo value se indica el objeto a afiadir. El siguiente ejemplo mostraria en la pagina el valor de la Propiedad “destino” del objeto “mensa”: <8:property value="destino"/> 85.2.5 SET : Asigna un valor a una vari: ‘1 ito. Sus Builadopahes variable y la deposita en un determinado ambito. - OE atignado al vaiale * value. Valor asignado a one = lable sere, Ambito de ta variable 5, TEqUES, “session” go, SY VBE puede ser “action” Predeterminado, ‘olicaion”, sendy =e _ Después de establecer tg Variable és siguiente ejemplo asigna una cagen 8 queda en el stack ge muestra su valor: de texto a Obsérvese como el valor de la y expresién. ariable apan 8.5.3 Acciones de control ‘Veamos a continuacién las principales acc grupo. iones q 8.5.3.1 IF Evaliia el cuerpo de la accién si se cumple la condicién estab atributo test. Dicha condicién debe dar por tanto como resultado un tipo boolean Al ejecutar el siguiente bloque de sentencias se mostrar el texto administrador” en la pagina de respuesta “usuario : <{--evaluado si condicionl es ru! 266 STRUTS test="condicion2"> wvaluado 91 condicionl es false y condicion2 es true--> acif> -evaluado #i condicionl y condicion2 son ambas false--> 8.5.3.2 ITERATOR La accin iterator se utiliza para recorrer una coleccién de tipo Collection» Iterator, Dispone de los siguientes atributos: «value, Coleccién sobre la que se realizard la iteracién, + id, Variable que contendré una referencia al elemento de tg coleccién correspondiente a Ia iteracién actual. Por ejemplo, si ListaTareas es una clase de tipo coleccién con ung propiedad agregar, cuyo método setdgregar() realiza la insercién de un nueva elemento en la coleccién, el siguiente grupo de sentencias afladirfa tres tareas a la coleccién para después recorrerla y mostrar la lista de tareas en la pagina, siendo “areas” la propiedad del clase ListaTareas que da acceso a la coleceién de elementos: sumar <6:param name="agregar" >restar <6:param nane="agregar" >mult iplicar RAMA 8.5.4 Acciones 8.5.4.1 FORM Genera una etic queta XHTML funcionalidad necesaria para evitar ce tipo
uuna vez que se han enviado los datos Eye MC de | action. Nombre de} o} Se utiliza este atribut bjeto Action que capturard to ta peticién seri Action actual, Us ier la peticién. Si no ada por el objeto 8.5.4.2 TEXTFIELD Genera una caja de texto de un @ linea. Como atributos més destacados tenemos: name, Nombre de la propiedad del objeto Action volearé el contenido del control. Con ayuda ¢ interceptores predefinidos de Struts 2, la informaci recogida en los campos del formulario es volcada directamente en las Propiedades del objeto Action indicado en los elementos , sin necesidad de incluir ninguna instruccién de cédigo ni elementos de configuracién adicionales. en la que se uno de los = value. Valor de inicializacién del control. 8.5.4.3 PASSWORD Genera una caja de texto de tipo password. Ademas de los ee yalue, cuyo significado es el mismo que en el caso de la << ss: se es oa control dispone del atributo showPassword de tipo boolean, ne Ane podemos indicar si queremos que se vean los caracteres intr preferimos mostrar un cardcter especial (false). 8.5.4.4 TEXTAREA = Genera una caja de texto multilinea. Los atributos name y value tienen el mismo significado que en los controles anteriores, 268 STRUTS _ er 8.5.4.5 SUBMIT bmit para realizar la peticién y Genera un botén de tipo sul : formulario, Mediante su atributo value se indica el texto que se quiere soe control mostra Para ver la potencia de estos elementos graficos volvamos de meV sig c : tilizdbamos un formulario XHTML para prictica 8,1. En ella ul er ae O00 daca eg + envi trie el sma SO 8 oe Soe para poder tener acceso al objeto HitpServietRequest y recuperar asi los datog qe formulario. Si en vez de una pagina XHTML hubiéramos utilizado una pégina Isp cy, os controles Struts 2 indicados anteriormente, nada de esto habria sido Necesarig puesto que ls contenidos de los campos de texto se pueden volear directameni, en Ias correspondientes propiedades del objeto Action. Con esta solucign pagina JSP de inicio quedaria: ext/html; charset-UTF-a" 45 uri-"/strute-tags" %> <¥@ page content Typ <4@ taglib prefixe" Validacién
Usuario:
Password: Edad:
Email:chtml:text property="email"/>
feubmit" value="Bntrar"/>
stroPassword public string getPwd return pwd; text (Servlet 8.5.4.6 RADIO Con esta accién es posible generar una lista de elementos XHTML de tipo radio. Su propiedad més importante ¢s list, la cual indicara el objeto de tipo lista cuyos datos serin utilizados para la generacion de Jos controles. Por ejemplo, si “dias” es una propiedad de tipo ArrayList en un objeto llamado “calendario” que almacena los nombres de los cinco dias Taborables de la semana y “agregar” es el gz, ee 270_STRUTS —_——— ee 270_STRUTS __ as ue permite aftadir un dia a la lista, el si is otones de radio, cada uno de los Siguiente bloaue ge spondiente: tendra nombre de la propiedad q sentencias generaré cinco texto asociado el nombre del dia corre name="calendario’ >lunes name="agregar’ wagregar*>martes sagregar">miércoles sagregar">jueves eccione dia --" 8,5.4.10 ACTIONERROR Aunque no se trata de un control grafico, la accién ‘evalidator namec*regex" class="com.opensymphony- xwork2.validato? validators .RegexPieldValidator"/> —_ eS ee eee ee | archivo xwork-2.0.4,jar también incluye este documento X] on enerarlo manualmente. Por otro nae lo sario tener que gen 1 WEB-INFllib de la aplicacién no seré necesario reajiat iable de entorno classpath. que no serd ne incluido en el directori ninguna operacién adicional en Ia vari s validadores, ¢s necesario activar el inter Ademés de declarar to! sari de validacién automatica: Struts encargado de poner en marcha el proceso Ir »yalidator" class="com.opensymphony, «interceptor name= nterceptor"/> xwork2 validator .Validationt tampoco es necesaria que la reali |, puesto que el documento de oun fe validador ademas de afiadirlo toe stac La anterior operacién explicitamente en nuestro struts.xm por defecto ya incluye el registro de est de validadores por defecto. 8.6.2 Utilizacién de yalidadores en una aplicacién La wtilizacién de estos validadores en una aplicaciOn Struts 2 es una tare tan solo tendremos que crear un archivo XML en el que > jue tremendamente sencill Jos campos del objeto Action a los que se asociaremos las reglas de validacién con Jas queramos aplicar. Este archivo XML tendré que nombrarse siguiendo el siguiente formato: claseaccion-validation.xml donde claseaccion se correspondera con el nombre de la elase a la que pertenece el objeto Action cuyos campos se quieren validar. s Por ejemplo, supongamos que tenemos una cl: i6 nplo, supong lase de accién Iam: Login.class, similar a la utilizada en una de las practicas analizadas en e capitulo, y que se encarga de comprobar los credenciales de un usuario suministrados desde una pagina de login: : package misclases; import com.opensymphony .xwork2.ActionSupport; public class Login extends ActionSupport { private String username; private String password; peblie String execute() throws Exception { if (getPassword() .equals ("admin") ) ll ————— STL sre 2 Feturn success, else return ERROR, PUbliC old setUsernane ge this.username . E ) Public strin, ing getUsername() ( return this.userna S.passvord; } La clase comprueba el campo password y si su valor es igual a “admin’ devolverd una de las constantes predefinidas en la interfaz. ActionSupport, que serd. interpretada como validacién correcta, Si quisiéramos afiadir una regla de validacién para forzar la entrada obligatoria de datos en ambos campos, tendriamos que crear un archivo llamado Login-validation.xml en el que asociariamos cada regla con cada campo, segin se indica en el siguiente listado: gnessage>Debes introducir un usuarioc/message> a ‘ i ebes introdueir un Pat swords! iti username"> Como vemos en el listado anterior, para cada campo afiaditemoy clementa cfcld> en el que se indicard mediante el subelemento habri que aftadir tantos como reglas se quieran aplicar al campo. Cada regla Ilevard su propio mensaje de error asociado a tive del elemento - ite indicar que este archivo debe estar situado en el migmg Es importa uf cuentre el archivo .class correspondiente a la clase de directorio en que s¢ en accion. Para forzar a que el usuario sea redireccionado de nuevo a la paging login en cose de incumplise las reglas de validacfOn, simplemente habria que afiadir una entrada cuyo valor de atributo name sea “input” en el ph de configuracién struts.xml: NS, caction names"Login" class="misclases.Login"> cresult>/pages/ok. jep cresult name="error">/pages/error.jap cresult name="input">/pages/login.jsp . " Para poder mostrar los mensajes de error en Ja p4gina de login cuando e| usuario sea redireccionado a ella al incumplir las reglas de validacién, ser4 necesario incluir el elemento en la pagina. ‘Si queremos que la validacin se realice en cliente, tan sdlo necesario state chen dite sat ISLE aaa ea ara incluyen los elementos graficos para la captura de los datos: ; ‘aciones Struts 2 respecio » ¢ Para simoiy SPECLO & Struts | oy ig una aplicacion, ellminando aa ecad gat Ctr ceonfiguracion XML para rea Heat esas funciones, “tiller ficheros ge Por ejemplo en las aplicaciones : clones que hacen up de configuracién de tipo ClateAccion-atidane™ spas os hive anotaciones que serdn introducidas en — SEF sustituidos por Propia clase de accién, f Para este ¢ MEKELO de a utilizacion de anotaciones. requiere durante la implementacion de a clase en validadores, ta realizacién de dos operaciones Action: Que la clase hey Tede ActionSupport. 1 Se encuentra en oj Paquete Propotciona una implemen de soporte del AP} funcionalid .8 clase ActionSupport, que om. opensymphony.xwork? Hacién por defecto de dive de Struts 2, entre ellas lad relativa a la valida as interfaces § las relacionadas con la i6n de datos, Importar el paquete Com. opensymphony.xwork2. validator, Annotations, Este proporciona todas las anotaciones asociadss a ada uno de los validadores predefinidos de Struts 2. Una Tealizadas las tareas anteriores, seri necesario incluir be anotacién @yalidator delante de la declaracién de Ja clase para que Struts 2 reconozca las anotaciones que incluiremos a continuaciGn para la validacién de los datos: package misclases; Amport com.opensymphony xwork2 J dondupport; Amport com. opensymphony .xwork2 .validator.annotat: 7 @validator public claes Login extends Actionsupport { ’ ficente 6s, pre aplcar valor sabre un dete campo se fie Neat a cots ssid a valdador dee el mon gi hed a ‘a validar, indicando entre paréntesis i falle la validaci6n det dato. : mostrar al usuario cuando i eee car el validador RequiredStringValidator sobre tos definir la clase Login de la siguiente 'y “password” habria que package misclases; import ‘com. opensymphony . xwork2 ,ActLonSuPPO=+7 import _com.opensymphony xWOrk2 vvalidator annotations. *; e@validator public class Login extends Actionsupport { private string username; private string password; public String execute() throws Exception { 4 (getPassword() equate ("admin")? return success; //constante definida //en Actionsupport else return ERROR; //constante definida //en ActionSupport } public void setUsername (String us) { this.username = us; } enoquiredstringValidator (message="debe introducir un usuario") public string getUsername() { return this.username; } public void setPassword(string pwd) { this.password = pwd; ) @Requiredstringvalidator (m debe introducir un password") public String getPassword(){ return this.password; } Lo anterior haria que no fuera i i i in- eee eee que no necesario definir el archivo Login: Apéndice 4 incorpors a la especificacién gp Tenguaje se conjunto de tecnologias J2EE 1.4, 0, la cual forma parte del El objetivo de este Lenguaje es reemplazar a la Clsicas expresiones JSP basadas en la utilizacién de édigo Java, contribuyendo etc la reduccién e incluso eliminacién en algunos casos de la utlizacion Ye seriptlets Java dentro de una pagina JSP, Mediante la utilizacién de sencilla instrucciones el lenguaje EL. psibiita el acceso a los parimettos enviados en una peticién, a las cookies oa los dates almacenados en cualquiera de los mbitos de la aplicacin Como otros lenguajes de programacién, EL soporta la utilizacién de operadores y palabras reservadas. Por sus caractersticas, el lenguaje EL constiuye un namie i la creacién de vi complemento de las acciones JSP de Struts para rea ebay atin més a reducir la complejidad de las paginas JSP en las aplicaciones MVC. Ve RAMA 280_ STRUTS EXPRESIONES EL. Las expresiones BL devaelven: umn YalOn al lugar de la pagina donde esté situada la expresion. Su sintaxis es: Sfexpresion} resin sintactica valida EL que devuelva up i pueden incluir referencias a variables JSP, objetos dos en cualquiera de los ambitos de aplicacién o tilizando alguno de los operadores donde expresion es cualquier exP! resultado. Estas expresion implicitos EL, datos almacena incluso alguna operacion entre datos ut soportados por EL. Por ejemplo, siendo “midato” el nombre de alguna variable JSP, |g siguiente instruceién mostraria el nombre de dicha variable en la pagina: 51 valor de 1a variable es ${midato} Lo anterior es equivalente a: zi valor de la variable es pero con la ventaja en el caso de EL de no tener que utilizar seriptlets Java. estacar que una expresion EL no puede acceder a dos en scriptlets Java. Por ejemplo, el siguiente bloque Es importante d la pagina puesto que la variable variables u objetos creat de sentencias no generarfa ningin resultado en “dato” no existiria para EL: resultado: ${dato} Las expresiones EL pueden utilizarse bien para generar un texto dentro de la pagina de respuesta o bien para establecer el valor de un atributo de alguna accién JSP (incluidos los tags de Struts) que acepte expresiones. El siguiente ejemplo utiliza una expresién EL para obtener el valor a asignar a la variable “parametro”: cbean:define id-"parametro" value="${param{'par']}"/> simbolos “S{" y «(> de mismo se llevard a S UN Obj enti dos propiedades: “usuario” y “passwords, cet Tticadot “ValidacionFomn” con desde una pigina ISP cualquiera dela api nee ambit sus propiedades deberiamos utilizar las expresionect oes Ot 0 de sesién y tener ie resiones: valor de $(ValidacionForm.usuario) y ${ValidacionForm, password} El siguiente bloque de instrucciones de ej 7 a es de ejemplo harfan que se mostrase e! texto “Mensaje de prueba” en la pgina de respuesta» ee ceed Mensaje:

${info.clave}

ink ="clave" value="Mensaje de prueba"/> Si el objeto es de tipo coleccién el acceso a sus elementos se realizar, en el caso de colecciones basadas en indices: $fobjeto_coleccion{indice]} mientras que para colecciones basadas en claves serd: $fobjeto_coleccion[“nombre_clave”]} En este iltimo caso tambign es posible utilizar fa siguiente expresion para acceder al valor del elemento de la colecct6 Sfobjeto_coleecion nombre clave) i RAMA 292_STRUTS j i jn de tipo Map llamada “based: Por ejemplo, si tenemos uns coleccién de tip eC Ia que se almacenan 10s nombres de personas asocidndoles como clave el DNI, la siguiente instruceién mostrard el ® Gmbre de Ia persona cuyo DNT sea 30005W: gu nombre es ${basedatos [»30005W") } OBJETOS IMPLiCITOS EL EI Ienguaje EL incluye una serie de objetos implicitos que permiten acceder de una forma sencilla a toda Ia informacién que los distintos objetos del ‘API servlet proporcionan a Ja aplicacién, como son las variables de pagina, peticidn, sesi6n 0 aplicacion, los etros ¥ encabezados de la peticion, las esokies y los pardmetros de contexto de inicializacion. « son expuestos como colecciones de tipo Map, accediéndose a das por éstos mediante la expresién: Estos objeto: porciona\ las propiedades y variables pro} $objeto_implicito[clave]} “clave” el nombre de Ia propiedad o variable cuyo valor se quiere obtener. siend tue forman parte del Ienguaje EL son: Los objetos implicitos qi + pageScope. Proporciona acceso a las variables de ambito de pagina. + requestScope. Proporciona acceso a las variables de Ambito de peticién. Por ejemplo, dado el siguiente bloque de sentencias incluidas en una pagina JSP: Math .random() *500) 7 request .setattribute ("codigo", Si quisiéramos mostrar en la pagina pruebajsp el valor de la variable de peticién “codigo”, utilizariamos: El cédigo generado es: ${ request Scope ["codigo"] } obj 4 i Durante este iiltimo apéndice estudiaremos las acciones mas importantes de esta libreria y los pasos a seguir para su utilizacién, INSTALACION DE JSTL i ha sido hasta la version Aunque es soportada desde la versién JSP 1.2, no J2EE 5.0 SP 2.1) cuando JSTL. se ha integra en la plaulorma J2EE. No obstante, podemos descargarla de forma independiente desde {ee 2s et ee eee m.com/procuctsijspist Dos son 1os archivos que proporcionlh todo el soporte para In utilizacign de JSTL: jsthjar y standard.jar, Tinbos deberin ser includes en el directorig WEB-INFllib de la aplicaci6n mos uti Inp:fjava.sW Es posible que si estal lizando_algiin entorno de desarrollo, especialmente si incluye soporte pars JDEE 5, los componentes de la libreria ie ssPrayan en otros archivos jar diferentes 4 Estos y sean incorporados de forma automatica al proyecto: JON DE ACCIONES JSTL archivos jar en el directorio de librerias podemos UTILIZAC. L. desde cualquiera de las paginas JSP de la Una vez desplegados los hacer uso de las acciones JSTI aplicacién. TL esté compuesto realmente por cinco coporeiona el grupo de acciones de ia utilizacion y sobre las que nos cciones JS’ libreria core la que Pr Jas de mas amp! EI conjunto de a librerfas, de las cuales es 1a uso general, que son en definitiva centraremos en este estudio. en una pagina JSP es necesario incluir Para poder utilizar las acciones core ctiva taglib en la pagina: Ia siguiente dire iava.sun.com/jsp/jstl/eore" pre <%6@taglib uri="hutp-Mfj n=" Como vemos, suele ser convenio utilizar el prefijo “e” para referirse a las acciones del core. ANALISIS DE LAS PRINCIPALES ACCIONES JSTL ‘A lo largo de esta seccién vamos a analizar las principales acciones 'STL. que componen la libreria core. Para facilitar nuestro estudio vamos & dividir este crnjunto de acciones en dos grupos, segiin la funcionalidad proporeionada por las mismas: * Acciones genéricas = Acciones de control de flujo <%=expresion%s> También es equivalent. un determinado valor en la contiene la expresién EL, a la accion Struts Pagina de respuesta. ue determina el valor a in, 8 decir, inserta Su principal atributo, value, cluir en la pagina. El siguiente mse con el valor del parametro “email” enviado en la <€:0uE value="$(param{‘enail')}+/s Se puede indicar mediante el a de ributo default un valor por defecto para ‘mostrar en la pagina en caso de que no s € localice el dato indicado en value: la direccién de correo electrénico es SET Se emplea para establecer un valor en una variable JSP, en una propiedad de un JavaBean 0 en una coleccién de tipo Map. Sus atributos son: = yar. Identificador de la variable JSP a la que se asignard el valor. = target. Objeto JavaBean 0 coleccién donde se asignara el valor. erty. Propi i Ja que se le asignaré el yroperty, Propiedad del objeto JavaBean a ; a JavaBean, property conten¢ afiadir a la coleccion. RAMA 290_STRUTS, del JavaBean o coleccién especificados en target, sj soe Capocitice exfe sttioio Me tees Mees as Et eee. “ oe ioe Ambitos de In aplicacion, siguiendo el orden: page request, session y application. ‘aré a la variable, propiedad de JavaBean Jos atributos anteriores se hayan «scope. Ambito value, Valor que se asign: 6 coleccién, segiin cusles de especificado. iguiente instrucei6n asigna el valor 40 a la vari retres" value="${5*8}"/> mplo se asigna el valor del pardmetro “telefono” a ta JavaBean “persona”: La sii jable “res”: ejemplo se asigna una cadena de caracteres ‘gna la coleccion “usuarios” de ambito de Finalmente, en este otro -omo clave asociada al objeto: existente en una variable de sesi aplicacin, utilizando el valor “xxx” © application" et targete"usuarios™ scope= {sessionScopel'user!]}"/> property="20x" value: REMOVE Flimina una variable existente en uno de los ambitos de la aplicacion. Sus atributos son: = yar. Identificador de la variable a eliminar. scope. Ambito donde se encuentra la variable. Si no se especifica se buscaré en todos los Ambitos de la aplicacion. CATCH Permite capturar una excepeién dentro de la pagina JSP. El formato de utilizacién de la accién es el siguiente: “clones posible excenciin S :catch> control del programa a a prin REDIRECT Realiza la mism HttpServletResponse, direccion estaré especificada en o attibuto uri de sei MH? Fs ou Duto ur! de la accién Opcionalmente Brae Ty aoc St Caviae parémetroe denies habré que utilizar la accién CHOOSE x formino os Sint aceién , sOlo que en este caso se comprucban varias condiciones ei dose el cuerpo de I8 PFIMETA GUE result hoose> es verdadera. La estructura de <° cuerpol shen> ce:when test="condicion2"> cuerpo? herwise /e:otherwise> EI siguiente ejemplo muestra distintos mensajes ©” la pagina de respuesta en funcion del valor de la variable hora esc pioeeetencnsemanenessnsee alor landose el cuerpo de « ¢l valor indicado en | ‘a variable al final de cada te el atributo step El siguiente bloque {a tabla de multiple, de acciones most: aria en la pagina de respuesta ar del niimero 7. Fe Recorrido de una coleccién, En este vat tecorreri la coleccién especific apuntado con la variable indicada en coleccién. El cuerpo de la accion sera e EI siguiente ejemplo mostrar en la coleccién “nombres”: Caso la variable indicada on ada en el. atributo items, var a cada elemento de la -valuado con cada iteracién. pagina el contenido de la chead> E oa ae varatdins! veriect ana el sein, juaven,, YisrHee, Gaunt domingo"/>
age anon ests é a 4 a s INDICE ALFABETICO acciones JSTL... action .. Action action, atributo . Action, objetos Struts 2 ActionContext. actionerror, accién ActionErrors ActionForm. ActionForward. ActionInvocation ActionMapping. ActionMessage i 124, 131 =e 40, 43, 121, 167 ere sae 7a ApplicationResource.properties..172, 183 ApplicationResources.properties ..38 _ applicationScope... 283 bean cookie define... Reet message. ne 73 page... Parameter byte, validador checkbox, acci 21 choose, accién.. 292 Controlador.. al controller. defaultStack . definicién definition.. definition, atributo destroy, método... DispatchAction double, validador doubleRange, validador ...- E -xpresiones, EL, lenguaje de expresiones .. EL, objetos implicitos... L, operadores. variables ccién.. email, validador empty, operador EL . excepciones.. Mas ExceptionHandlet «1. ute, método....40, 41, 44. 62, 85, 88, 89, 102, 123, 135, 222, 238, 244, 253 .171, 179, 276 field. Field field-validator fieldValue, atributo FileUploadinterceptor FilterDispatcher .. FilterDispatcher..... findForward(), método. float, validador foreach, accion. form .. form, acci6r form-bean, form-beans.... getInputForward(), método . getInvocationContext, método ... getKeyMethodMap, método ...... 102 getParameters, método... getPathInfo, métod getSession, método ...... getValueAsString, métod global-exception.. global-forward. H handler, atributo.. header headerKey, atributo. headerValue, atributo header Values href, atributo. HTML html:radio. lect. ibmit . xtarea HttpServletRequest.. if, accién . 265,291 include ... init, método - 3 init-param. 52 integer, validador eet intercept, método . 5 interceptor...” Interceptor, interfaz 5 interceptores.... 221,240 Iintereeptores personalizados .....253 interceptor-ref 242 interceptor-stack... 242 peemueiealidador hey invoke, método iterator, accién J J2EE. 21, 23,37 JavaBean 24 291 JSTL, acciones genéric; JSTL, instalacién .. ISTL, libreria de acciones ISTL, utilizacién..... K key, atributo.. 131 L lenguaje de expresione __ tones lessThan 50 match 180 NOMatci % Ss notE qual 150 Tedirect % Logic an logic, libreria 146 long, validador 181 LookupDispatchAcion 102 M MappingDispatchAction 109 mask, validador 1 maxlength, atributo maxlength, validador Message method, atributo minlength, validador Modelo Modelo Vista Controlador 20, msg, 184 msg, atributo 170, 196 MVC... ‘ 219 N Nest 2 ° operador condicional EL. 285 operadores EL.. 2 out, accién, PrincipalAware processActionCreate, processActionForm, método processActionPerform, método. processForwardConfig, método. processMapping, métod processorClass, atributo processPath, método processPopulate, método. processPreprocess, método process Validate, método propel property, atributo .. push, accién PU radio, accion... readonly, atributo redirect, accién... remove, acci6n.. RequestAware RequestProcessor. requestScops reset, método. est enn select, accion... sendRedirect, método, showPassword, Struts Struts 2. Struts 2, archivo de configuracién223 Struts 2, clases de accién. Struts 2, componentes Struts 2, interceptores. Struts 2, libreria de acciones Struts 2, librerfas de acciones. Struts 2, requerimientos Struts 2, validadore: Struts, API. Struts, archivo de configuracién . Struts, componentes ... Struts, control de excepcions Struts, estructura de aplicaciones .. 51 Struts, instalacion Struts, libreria de acciones Struts, librerias Struts, tiles ... Struts, validadores.. struts.xml.. struts-config.xml struts-default.xm! StrutsStaties submit, accion a taglib, directiva .....65, 140, 146, 199, 262, 288 textarea, accién . textfield, accién.. vo 267 +1 267 ee AST 42 199 tiles:getAsString 200 tiles:insert ..-199, 203, 208 204 tiles-definitions 206 tiles-defs.xml ‘ 39, 206 try-catch, ae -130 type, atributo. 131,276 U uri, atributo 65 url-pattern 52 iv validadores. 167, 179 validadores predefinidos .....1cu:-189 validadores Struts 2... 272 INDICE ALFARENCO 295 validate, atributo 216 validate, método....55, 123, 167, 171 189 validation xml Validator Validator ValidatorAction, ValidatorForm. Yalidator-rules.xml var var-value ‘: 180 Vista n w WebWork. 219 x XHTML Esta edicin se tering de or ALFAOMEGA GRU \partado Postal 73-267, 09311, Mésico, DF La lmpresién y encuademac; e0 FORMACION GRAF ‘Ade C.V., Matamoros No, 112, ColRail Romero $7630, Cay SUT Pchahindiiaae Raat ee aplicaciones Web madernas se esta raduciendo en un aumento de ~ esarrolios, haciendo indispensable en la cn mayoria de los casos el empleo de agin pte Ree ee eu te uta Lara te ae Ge Rema ae est aa en eine a ioe Soe eee eeu ere: Ce ee Re one ee Cee En este libro se analiza tanto la Cue oa mismo que nos ofrece la ultima version de Struts, Fe ie Nes Ce eee ere Recs te Dee eek een ee Lee eeu et) ee ea Re Dee eae eer ere ate a Pou ete eee eet ea LS) eT Le eet ocak nie www.alfaomega.com.mx A Alfaomega Grupo Editor Lr metodologia de desarrollo y el amplio conjunto de utilidades y componentes e Lens I

You might also like

ecrout value="${dia}"/>