96
Arquitectura WEB Arquitectura WEB Conceptos Conceptos Avanzados Avanzados

Arquitectura J2EE Struts

Embed Size (px)

DESCRIPTION

Clase Teórica de Hoy

Citation preview

Page 1: Arquitectura J2EE Struts

Arquitectura WEBArquitectura WEBConceptos AvanzadosConceptos Avanzados

Page 2: Arquitectura J2EE Struts

ObjetivosObjetivos

Reconocer y Aplicar Arquitectura de Reconocer y Aplicar Arquitectura de AplicacionesAplicaciones

Reconocer Plataformas de Desarrollo Reconocer Plataformas de Desarrollo empresarialesempresariales

Modelo Vista ControladorModelo Vista Controlador

Page 3: Arquitectura J2EE Struts

ContenidosContenidos

Arquitectura de aplicaciones Web.Arquitectura de aplicaciones Web. Plataformas de Desarrollo Plataformas de Desarrollo

Empresariales.Empresariales. Arquitecturas J2EE y Plataforma SAP Arquitecturas J2EE y Plataforma SAP

NW.NW. Introducción a la Arquitectura Orientada Introducción a la Arquitectura Orientada

a Servicios.a Servicios. Modelo Vista Controlador (MVC).Modelo Vista Controlador (MVC). Implementación del MVC.Implementación del MVC.

Page 4: Arquitectura J2EE Struts

ActividadesActividades

Exposición de contenidos.Exposición de contenidos. Instalación de IDE para ejercicioInstalación de IDE para ejercicio Ejercicio laboratorio de “Aplicación Ejercicio laboratorio de “Aplicación

del MVC”del MVC” Definición de grupos de trabajoDefinición de grupos de trabajo Especificar Trabajos grupalesEspecificar Trabajos grupales

Page 5: Arquitectura J2EE Struts

Arquitectura de AplicacionesArquitectura de Aplicaciones Definición de arquitectura usada por ANSI/IEEE Std Definición de arquitectura usada por ANSI/IEEE Std

1471-2000:1471-2000: "Es la organización fundamental de un sistema, "Es la organización fundamental de un sistema,

incorporada a sus componentes, su relación con cada incorporada a sus componentes, su relación con cada uno, el medio ambiente, y los principios que lo uno, el medio ambiente, y los principios que lo gobiernan, su diseño y evolución." gobiernan, su diseño y evolución."

Una Arquitectura es una herramienta conceptual que Una Arquitectura es una herramienta conceptual que asiste a las organizaciones con el entendimiento de su asiste a las organizaciones con el entendimiento de su propia estructura y su manera de trabajar. propia estructura y su manera de trabajar.

Provee un mapa de la ruta planeada para el sistema en Provee un mapa de la ruta planeada para el sistema en relación al cambio tecnológico.relación al cambio tecnológico.

Los modelos incluyen: Los modelos incluyen: Objetivos y MetasObjetivos y Metas Procesos y organizaciónProcesos y organización Sistemas y datosSistemas y datos Tecnología usada Tecnología usada

Page 6: Arquitectura J2EE Struts

Arquitectura de Aplicaciones (2)Arquitectura de Aplicaciones (2)

Diseño de arquitectura de sistema Diseño de arquitectura de sistema basado en:basado en:

ArtefactosArtefactos Casos de usoCasos de uso Línea de producto.Línea de producto. DominiosDominios PatronesPatrones

Page 7: Arquitectura J2EE Struts

.NET.NET

Page 8: Arquitectura J2EE Struts

J2EEJ2EE

Page 9: Arquitectura J2EE Struts

Paralelo .NET / J2EEParalelo .NET / J2EE

Page 10: Arquitectura J2EE Struts

Un Un Java Application ServerJava Application Server (ya denominado (ya denominado Application ServerApplication Server) ) proporciona el ambiente necesario para ejecutar EJB's y su estructura es la proporciona el ambiente necesario para ejecutar EJB's y su estructura es la siguiente: siguiente:

Los dos componentes principales de un Los dos componentes principales de un Application ServerApplication Server son el "Servlet son el "Servlet Engine" (Web-Container) y "Enterprise Bean Engine" (Bean-Container) Engine" (Web-Container) y "Enterprise Bean Engine" (Bean-Container) aunque no sean comercializados como tal. Dentro del "Servlet Container" aunque no sean comercializados como tal. Dentro del "Servlet Container" residen y se ejecutan JSP's y Servlet's, mientras que en el "Enterprise Bean residen y se ejecutan JSP's y Servlet's, mientras que en el "Enterprise Bean Container" se ejecutan los EJB's. Container" se ejecutan los EJB's.

Java Application ServersJava Application Servers

Page 11: Arquitectura J2EE Struts

Application servers fully J2EE Application servers fully J2EE CompliantCompliant

Existen varios en el mercado. Entre los mas usados:Existen varios en el mercado. Entre los mas usados: Sun Application Server Sun Application Server (gratuito para desarrolladores)(gratuito para desarrolladores) Apache Tomcat Apache Tomcat (Open Source - gratuito)(Open Source - gratuito) JBoss JBoss (Open Source – gratuito)(Open Source – gratuito) Oracle 10g Application Server Oracle 10g Application Server (descarga gratuita)(descarga gratuita) IBM Websphere IBM Websphere (bajo licencia comercial)(bajo licencia comercial) BEA WebLogic BEA WebLogic (bajo licencia comercial)(bajo licencia comercial) SAP WAS NW SAP WAS NW (bajo licencia comercial)(bajo licencia comercial)

En estos "Application Servers" no existe una clara distinción (al En estos "Application Servers" no existe una clara distinción (al menos para el programador final) entre el "Servlet Engine" y el menos para el programador final) entre el "Servlet Engine" y el "EJB Engine" por lo que la ejecución de componentes se lleva "EJB Engine" por lo que la ejecución de componentes se lleva acabo de una manera relativamente transparente. acabo de una manera relativamente transparente.

Puede consultar detalles adicionales sobre Servidores de Páginas y de aplicaciones en:Puede consultar detalles adicionales sobre Servidores de Páginas y de aplicaciones en: "Web "Web ServersServers" y "Java " y "Java ApplicationApplication ServersServers""

Page 12: Arquitectura J2EE Struts

Herramientas e IDEs J2EE Herramientas e IDEs J2EE Independientemente del Independientemente del Application ServerApplication Server que se esté que se esté

utilizando, seguramente existirá una herramienta que utilizando, seguramente existirá una herramienta que automatiza ciertos pasos de la creación de un EJB. automatiza ciertos pasos de la creación de un EJB.

El grado de automatización puede variar desde el El grado de automatización puede variar desde el "Deployment Descriptor" hasta la creación de WAR's y "Deployment Descriptor" hasta la creación de WAR's y EAR's.EAR's.

Desde luego presentan una gran ventaja. Por ejemplo: un Desde luego presentan una gran ventaja. Por ejemplo: un "Deployment Descriptor" puede contener 100 o 200 líneas "Deployment Descriptor" puede contener 100 o 200 líneas de código que puede tomar horas en escribir. Esto puede de código que puede tomar horas en escribir. Esto puede ser reducido con estas herramientas a unos cuantos ser reducido con estas herramientas a unos cuantos minutos al llenar formularios.minutos al llenar formularios.

A pesar de sus ventajas, muchas de estas herramientas A pesar de sus ventajas, muchas de estas herramientas ofrecen funcionalidades mínimas. ofrecen funcionalidades mínimas.

Hoy en día ya existen diversos IDE's ("Integrated Hoy en día ya existen diversos IDE's ("Integrated Development Environments") que permiten no sólo las Development Environments") que permiten no sólo las tareas anteriores, sino que también agilizan la creación de tareas anteriores, sino que también agilizan la creación de código fuente para EJB's tales como: creación de Interfases, código fuente para EJB's tales como: creación de Interfases, conexiones hacia Bases de Datos y otras facilidades más.conexiones hacia Bases de Datos y otras facilidades más.

Page 13: Arquitectura J2EE Struts

Algunos IDE'sAlgunos IDE's

NetBeansNetBeans Open-Source Open-Source Eclipse Eclipse Open-Source Open-Source Sun Java Studio Sun Java Studio CreatorCreator SunSun JBuilderJBuilder Borland Borland WebSphereWebSphere Studio Studio IBM IBM JDeveloperJDeveloper OracleOracle NW Developer StudioNW Developer Studio SAPSAP Workshop Workshop BEA WeblogicBEA Weblogic

Page 14: Arquitectura J2EE Struts

Arquitectura J2EEArquitectura J2EE

modelo de aplicaciones distribuidas en diversas capas o niveles (tier).

•Cliente•Intermedia•Sistema Información Empresarial (back end)

Escenario basado en la web (web-centric application)

Escenario desde un navegador:

Escenario desde una aplicación

Page 15: Arquitectura J2EE Struts

Capas de la Arquitectura J2EECapas de la Arquitectura J2EE En la arquitectura JEE se contemplan cuatro capas, en función En la arquitectura JEE se contemplan cuatro capas, en función

del tipo de servicio y contenedores:del tipo de servicio y contenedores: Capa de Capa de clientecliente, también conocida como capa de presentación , también conocida como capa de presentación

o de aplicación. Nos encontramos con componentes Java o de aplicación. Nos encontramos con componentes Java (applets o aplicaciones) y no-Java (HTML, JavaScript, etc.). (applets o aplicaciones) y no-Java (HTML, JavaScript, etc.).

Capa Capa WebWeb. Intermediario entre el cliente y otras capas. Sus . Intermediario entre el cliente y otras capas. Sus componentes principales son los servlets y las JSP. Aunque componentes principales son los servlets y las JSP. Aunque componentes de capa cliente (applets o aplicaciones) pueden componentes de capa cliente (applets o aplicaciones) pueden acceder directamente a la capa EJB, lo normal es que Los acceder directamente a la capa EJB, lo normal es que Los servlets/JSPs pueden llamar a los EJB. servlets/JSPs pueden llamar a los EJB.

Capa Capa Enterprise JavaBeansEnterprise JavaBeans. Permite a múltiples aplicaciones . Permite a múltiples aplicaciones tener acceso de forma concurrente a datos y lógica de negocio. tener acceso de forma concurrente a datos y lógica de negocio. Los EJB se encuentran en un servidor EJB, que no es más que Los EJB se encuentran en un servidor EJB, que no es más que un un servidor de objetos distribuidosservidor de objetos distribuidos. Un EJB puede . Un EJB puede conectarse a cualquier capa, aunque su misión esencial es conectarse a cualquier capa, aunque su misión esencial es conectarse con los sistemas de información empresarial (un conectarse con los sistemas de información empresarial (un gestor de base de datos, ERP, etc.)gestor de base de datos, ERP, etc.)

Capa de Capa de sistemas de información empresarialsistemas de información empresarial..

Page 16: Arquitectura J2EE Struts

La visión de la arquitectura es La visión de la arquitectura es un un esquema lógicoesquema lógico, no físico, no físico

Page 17: Arquitectura J2EE Struts

Patrón o Micro arquitectura Patrón o Micro arquitectura Modelo-Vista-Controlador Modelo-Vista-Controlador

(MVC)(MVC) Elementos del patrón: Elementos del patrón:

Modelo: datos y reglas de negocio. Modelo: datos y reglas de negocio. Vista: muestra la información del modelo al usuario.Vista: muestra la información del modelo al usuario. Controlador: gestiona las entradas del usuario.Controlador: gestiona las entradas del usuario.

Page 18: Arquitectura J2EE Struts

Implementación Web de MVCImplementación Web de MVC

Diagrama de Secuencia:Diagrama de Secuencia:

Pasos: Pasos: El usuario introduce el evento. El usuario introduce el evento. El Controlador recibe el evento y lo traduce en una petición al El Controlador recibe el evento y lo traduce en una petición al

Modelo (aunque también puede llamar directamente a la vista). Modelo (aunque también puede llamar directamente a la vista). El modelo (si es necesario) llama a la vista para su actualización. El modelo (si es necesario) llama a la vista para su actualización. Para cumplir con la actualización la Vista puede solicitar datos al Para cumplir con la actualización la Vista puede solicitar datos al

Modelo. Modelo. El Controlador recibe el control. El Controlador recibe el control.

Page 19: Arquitectura J2EE Struts

Ejemplo MVC en J2EE usando Ejemplo MVC en J2EE usando STRUTSSTRUTS

StrutsStruts es una herramienta de soporte para el es una herramienta de soporte para el desarrollo de desarrollo de aplicaciones Webaplicaciones Web bajo el bajo el patrónpatrón MVCMVC bajo la plataforma bajo la plataforma J2EEJ2EE (Java 2, Enterprise (Java 2, Enterprise Edition). Edition).

Se desarrollaba como parte del proyecto Se desarrollaba como parte del proyecto JakartaJakarta de la de la Apache Software Apache Software FoundationFoundation, , pero actualmente es un proyecto pero actualmente es un proyecto independiente conocido como independiente conocido como Apache Apache StrutsStruts..

Struts permite reducir el tiempo de desarrollo. Struts permite reducir el tiempo de desarrollo. Su carácter de "Su carácter de "software libresoftware libre" y su " y su

compatibilidad con todas las plataformas en compatibilidad con todas las plataformas en que Java Entreprise esté disponible, lo que Java Entreprise esté disponible, lo convierte en una herramienta altamente convierte en una herramienta altamente disponible.disponible.

Page 20: Arquitectura J2EE Struts

Arquitectura funcional básicaArquitectura funcional básica

Page 21: Arquitectura J2EE Struts

Arquitectura funcional básica (2)Arquitectura funcional básica (2)

Page 22: Arquitectura J2EE Struts

Funcionalidad deseadaFuncionalidad deseada Se trata de una aplicación de alta de usuario, un tipo de Se trata de una aplicación de alta de usuario, un tipo de

aplicación muy común y que presenta en muchos aplicación muy común y que presenta en muchos sistemas. sistemas.

Implementar con Struts . Implementar con Struts . En cualquier otro entorno bastaría con crear un En cualquier otro entorno bastaría con crear un

formulario y una página que realiza el alta y da el formulario y una página que realiza el alta y da el mensaje correspondiente; pero aquí no será tan simple.mensaje correspondiente; pero aquí no será tan simple.

Entrada de aplicación: Entrada de aplicación: Un formulario de datos: Un formulario de datos:

username, username, password, password, edad, edad, fechanacimiento y fechanacimiento y profesiónprofesión

Salida de aplicación : Salida de aplicación : Una página que muestra si se ha dado de alta Una página que muestra si se ha dado de alta

correctamente.correctamente.

Page 23: Arquitectura J2EE Struts

Diagrama de clasesDiagrama de clases

Page 24: Arquitectura J2EE Struts

Diagrama de ColaboraciónDiagrama de Colaboración

Page 25: Arquitectura J2EE Struts

Referencias en InternetReferencias en Internet http://http://jakarta.apache.orgjakarta.apache.org//strutsstruts http://http://jakarta.apache.orgjakarta.apache.org//strutsstruts//userGuideuserGuide http://jakarta.apache.org/struts/http://jakarta.apache.org/struts/#Involved#Involved http://http://jakarta.apache.orgjakarta.apache.org//strutsstruts//apiapi http://http://jguru.comjguru.com//faqfaq//StrutsStruts http://jguru.com/forums/Strutshttp://jguru.com/forums/Struts http://www-128.ibm.com/developerworks/library/j-strhttp://www-128.ibm.com/developerworks/library/j-str

uts/?dwzone=javauts/?dwzone=java http://www.programacion.com/java/tutorial/struts/http://www.programacion.com/java/tutorial/struts/ http://www.programacion.com/java/tutorial/joa_strutshttp://www.programacion.com/java/tutorial/joa_struts

// http://http://www.monografias.comwww.monografias.com/trabajos28//trabajos28/strutsstruts

-el-netbeans4/-el-netbeans4/strutsstruts-el-netbeans4.-el-netbeans4.shtmlshtml

Page 26: Arquitectura J2EE Struts

Apache Jakarta StrutsApache Jakarta StrutsFuente: Dr. Diego Lz. de Ipiña Gz. de ArtazaFuente: Dr. Diego Lz. de Ipiña Gz. de Artazahttp://paginaspersonales.deusto.es/dipinahttp://paginaspersonales.deusto.es/dipina

http://paginaspersonales.deusto.es/dipina/cursos/http://paginaspersonales.deusto.es/dipina/cursos/J2EECesine.zipJ2EECesine.zip

[email protected]@eside.deusto.es

Page 27: Arquitectura J2EE Struts

ContenidoContenido Patrón de diseño MVCPatrón de diseño MVC La framework Apache StrutsLa framework Apache Struts

InstalaciónInstalación Flujo de control en StrutsFlujo de control en Struts

Procesamiento de peticionesProcesamiento de peticiones Control de erroresControl de errores Manejo de FormulariosManejo de Formularios

Librerías de etiquetas de StrutsLibrerías de etiquetas de Struts InternacionalizaciónInternacionalización

Ejemplo de aplicación StrutsEjemplo de aplicación Struts Java Server FacesJava Server Faces

Page 28: Arquitectura J2EE Struts

Modelos de desarrollo de Modelos de desarrollo de aplicaciones web en Javaaplicaciones web en Java

Los servlets son buenos ejecutando lógica de Los servlets son buenos ejecutando lógica de negocio, pero no son tan buenos presentando negocio, pero no son tan buenos presentando informacióninformación

JSPs son muy buenos presentando pero pésimos JSPs son muy buenos presentando pero pésimos introduciendo lógica programática en ellosintroduciendo lógica programática en ellos

La combinación Servlet/JSPs es lo más común hoy en La combinación Servlet/JSPs es lo más común hoy en día en el desarrollo de aplicaciones webdía en el desarrollo de aplicaciones web

Dos arquitecturas:Dos arquitecturas: Model-1: JSPs para presentación y control y JavaBeans Model-1: JSPs para presentación y control y JavaBeans

para la lógicapara la lógica Model-2: Model-View-Controller = JavaBeans-JSPs-Model-2: Model-View-Controller = JavaBeans-JSPs-

ServletsServlets MVC es tan común que se han desarrollado varias MVC es tan común que se han desarrollado varias

infraestructuras en torno a este patrón de diseño:infraestructuras en torno a este patrón de diseño: Apache StrutsApache Struts Java Server FacesJava Server Faces

Page 29: Arquitectura J2EE Struts

Arquitectura Model 1Arquitectura Model 1

Page 30: Arquitectura J2EE Struts

Arquitectura Model 2Arquitectura Model 2

Page 31: Arquitectura J2EE Struts

Modelo MVC 0Modelo MVC 0

Page 32: Arquitectura J2EE Struts

Modelo MVC IModelo MVC I

El Controlador (Controller)El Controlador (Controller) Servlet central recibe peticiones, procesa Servlet central recibe peticiones, procesa

URL recibida y delega procesamiento a URL recibida y delega procesamiento a JavaBeansJavaBeans

Servlet guarda resultado de Servlet guarda resultado de procesamiento realizado por JavaBeans en procesamiento realizado por JavaBeans en el contexto de la petición, la sesión o la el contexto de la petición, la sesión o la aplicaciónaplicación

Servlet transfiere control a un JSP que Servlet transfiere control a un JSP que lleva a cabo la presentación de resultadoslleva a cabo la presentación de resultados

Page 33: Arquitectura J2EE Struts

Modelo MVC IIModelo MVC II

El Modelo (Model)El Modelo (Model) JavaBeans (o EJBs para aplicaciones JavaBeans (o EJBs para aplicaciones

más escalables) desempeña el rol de más escalables) desempeña el rol de modelo:modelo:

Algunos beans ejecutan lógicaAlgunos beans ejecutan lógica Otros guardan datosOtros guardan datos

Normalmente: Normalmente: 1.1. Servlet controlador invoca un método en Servlet controlador invoca un método en

bean lógico y éste devuelve un bean de bean lógico y éste devuelve un bean de datosdatos

2.2. Autor de JSP tiene acceso a bean de datosAutor de JSP tiene acceso a bean de datos

Page 34: Arquitectura J2EE Struts

Modelo MVC IIIModelo MVC III

La Vista (View)La Vista (View) Rol ejecutado por JSPsRol ejecutado por JSPs Servlet Controlador transfiere control Servlet Controlador transfiere control

al JSP después de haber guardado en al JSP después de haber guardado en un contexto el resultado en forma de un contexto el resultado en forma de un bean de datosun bean de datos

JSP usa JSP usa jsp:useBeanjsp:useBean y y jsp:getPropertyjsp:getProperty para recuperar para recuperar datos y formatear respuesta en HTML datos y formatear respuesta en HTML o XMLo XML

Page 35: Arquitectura J2EE Struts

Modelo MVC IVModelo MVC IV

En resumen:En resumen: Los beans o EJBs ejecutan la lógica de Los beans o EJBs ejecutan la lógica de

negocio y guardan los resultadosnegocio y guardan los resultados Los JSPs proveen la información Los JSPs proveen la información

formateadaformateada Los servlets coordinan/controlan la Los servlets coordinan/controlan la

ejecución de los beans y los JSPsejecución de los beans y los JSPs

Page 36: Arquitectura J2EE Struts

FrameworksFrameworks

Las frameworks pueden ser vistas como Las frameworks pueden ser vistas como implementaciones de patrones de diseño que implementaciones de patrones de diseño que facilitan la reutilización de diseño y códigofacilitan la reutilización de diseño y código

Dado que MVC ha sido utilizado en muchas Dado que MVC ha sido utilizado en muchas aplicaciones web, el desarrollo de frameworks aplicaciones web, el desarrollo de frameworks que den soporte a áreas comunes en todas que den soporte a áreas comunes en todas las aplicaciones MVC es necesariolas aplicaciones MVC es necesario Apache Struts es una de estas frameworksApache Struts es una de estas frameworks

Aplicaciones basadas en Struts consistirán de:Aplicaciones basadas en Struts consistirán de: Código Java Código Java Deployment descriptors que configuran la Deployment descriptors que configuran la

framework para el uso de nuestra aplicaciónframework para el uso de nuestra aplicación

Page 37: Arquitectura J2EE Struts

Apache Jakarta StrutsApache Jakarta Struts

Implementación del modelo 2/patrón Implementación del modelo 2/patrón de diseño MVC que facilita la de diseño MVC que facilita la creación de aplicaciones web en Javacreación de aplicaciones web en Java

Creada por Craig McClanahan y Creada por Craig McClanahan y donada a la Apache Software donada a la Apache Software Foundation en el 2000 (pertenece a Foundation en el 2000 (pertenece a Apache Jakarta)Apache Jakarta)

Page 38: Arquitectura J2EE Struts

¿Qué proporciona Struts?¿Qué proporciona Struts?

Un servlet (Un servlet (ActionServletActionServlet) que actúa como controlador ) que actúa como controlador MVC totalmente configurableMVC totalmente configurable

Clases base que son extendidas para implementar la Clases base que son extendidas para implementar la lógica de la aplicación web:lógica de la aplicación web: Struts Struts ActionAction Struts Struts ActionFormActionForm

Un rico conjunto de etiquetas personalizadas JSP que Un rico conjunto de etiquetas personalizadas JSP que cooperan con el controlador para su uso en la capa view cooperan con el controlador para su uso en la capa view de MVCde MVC

Varias opciones para la validación de entrada de usuario Varias opciones para la validación de entrada de usuario en formularios HTML: en formularios HTML: ActionFormActionForm o o ValidatorValidator FrameworkFramework

Mecanismos para el manejo y reporte de erroresMecanismos para el manejo y reporte de errores Soporte para la internacionalización (i18n) a través de Soporte para la internacionalización (i18n) a través de

ficheros de recursos y Java Localesficheros de recursos y Java Locales Soporte para fuentes de datosSoporte para fuentes de datos Y más …..Y más …..

Page 39: Arquitectura J2EE Struts

Instalando Apache Struts IInstalando Apache Struts I Instalar Apache Tomcat 4.x o superiorInstalar Apache Tomcat 4.x o superior Bajar la última versión de Apache Struts de: Bajar la última versión de Apache Struts de:

http://struts.apache.org/download.cgihttp://struts.apache.org/download.cgi Actualmente en la versión 1.2 (fichero jakarta-struts-1.2.4.zip Actualmente en la versión 1.2 (fichero jakarta-struts-1.2.4.zip

para Windows)para Windows) Crear directorio de aplicación. E.j: Crear directorio de aplicación. E.j: myStrutsAppmyStrutsApp Copiar ficheros Copiar ficheros .tld.tld en directorio en directorio

{StrutsDirectory}/contrib/struts-el/lib{StrutsDirectory}/contrib/struts-el/lib a a myStrutsApp/WEB-INFmyStrutsApp/WEB-INF:: c.tldc.tld struts-bean-el.tldstruts-bean-el.tld struts-html-el.tldstruts-html-el.tld struts-logic-el.tldstruts-logic-el.tld

Page 40: Arquitectura J2EE Struts

Instalando Apache Struts IIInstalando Apache Struts II Copiar Copiar los ficheros .jar files de los ficheros .jar files de

{StrutsDirectory}/contrib/struts-el/lib{StrutsDirectory}/contrib/struts-el/lib a a myStrutsApp/WEB-INF/libmyStrutsApp/WEB-INF/lib directory: directory: commons-beanutils.jarcommons-beanutils.jar commons-collections.jarcommons-collections.jar commmons-digester.jarcommmons-digester.jar commons-logging.jarcommons-logging.jar jstl.jarjstl.jar standard.jarstandard.jar struts-el.jarstruts-el.jar struts.jarstruts.jar

Lo mejor es tomar la aplicación Lo mejor es tomar la aplicación struts-blank.warstruts-blank.war como como punto de partida.punto de partida.

Page 41: Arquitectura J2EE Struts

Documentación y ejemplos de Documentación y ejemplos de Struts Struts

En el directorio En el directorio webappswebapps de la de la distribución de Struts 1.2 se pueden distribución de Struts 1.2 se pueden encontrar varios ficheros .war muy encontrar varios ficheros .war muy útiles:útiles: struts-documentation.warstruts-documentation.war

En el subdirectorio En el subdirectorio api/index.htmlapi/index.html se puede se puede encontrar JavaDoc de Struts APIencontrar JavaDoc de Struts API

Si se ejecuta esta aplicación web en Si se ejecuta esta aplicación web en http://localhost:8080/struts-documentation/ se http://localhost:8080/struts-documentation/ se puede también obtener información detallada puede también obtener información detallada sobre el uso de Strutssobre el uso de Struts

Ejemplos de uso de Struts: Ejemplos de uso de Struts: struts-examples.warstruts-examples.war struts-blank.warstruts-blank.war base para la creación de base para la creación de

cualquier aplicación que use Struts cualquier aplicación que use Struts etc.etc.

Page 42: Arquitectura J2EE Struts

Flujo de Control en Struts IFlujo de Control en Struts I

Page 43: Arquitectura J2EE Struts

Flujo de Control en Struts IIFlujo de Control en Struts II

Page 44: Arquitectura J2EE Struts

Flujo de control en Struts IIIFlujo de control en Struts III

La clase La clase org.apache.struts.action.ActionServletorg.apache.struts.action.ActionServlet es el eje de Struts. es el eje de Struts. Dada una petición de entrada HTTP:Dada una petición de entrada HTTP:

Crea un objeto Crea un objeto ActionFormActionForm donde guarda y valida los parámetros de entrada donde guarda y valida los parámetros de entrada Decide que objeto Decide que objeto ActionAction se debe invocar y le pasa el objeto se debe invocar y le pasa el objeto ActionFormActionForm creado creado Transfiere control a la siguiente etapa de procesamiento de la petición Transfiere control a la siguiente etapa de procesamiento de la petición

(típicamente un JSP).(típicamente un JSP). El fichero de configuración El fichero de configuración web.xml web.xml contiene los url mappings para enviar contiene los url mappings para enviar

las peticiones de llegada al las peticiones de llegada al ActionServlet, ActionServlet, mientras que el fichero de mientras que el fichero de configuración de Struts configuración de Struts struts-config.xmlstruts-config.xml contiene los mappings a contiene los mappings a accionesacciones

Los form beans creados por Los form beans creados por ActionServletActionServlet deben ser implementados por deben ser implementados por el programador, extendiendo el programador, extendiendo org.apache.struts.action.ActionFormorg.apache.struts.action.ActionForm..

El programador deberá definir un conjunto de getters y setter y sobreescribir los El programador deberá definir un conjunto de getters y setter y sobreescribir los métodos métodos validate()validate() y y reset()reset()

Los objetos Los objetos ActionAction invocados deben ser desarrollados por el programador invocados deben ser desarrollados por el programador y extienden y extienden org.apache.struts.action.Actionorg.apache.struts.action.Action. Tienen un método . Tienen un método execute()execute() o ( o (perform()perform() en Struts 1.0) que ejecuta la lógica de negocio en Struts 1.0) que ejecuta la lógica de negocio

La acción devuelve un objeto La acción devuelve un objeto ActionForwardActionForward al servlet que especifica el al servlet que especifica el siguiente paso a ejecutar, normalmente se transfiere el control a un JSP siguiente paso a ejecutar, normalmente se transfiere el control a un JSP para que visualice los resultados.para que visualice los resultados.

Page 45: Arquitectura J2EE Struts

Pasos a seguir en el desarrollo Pasos a seguir en el desarrollo de una aplicación en Strutsde una aplicación en Struts

Diseña la aplicación en términos de las acciones, vistas y estados Diseña la aplicación en términos de las acciones, vistas y estados del modelodel modelo

Añade las librerías Java de Struts y los .tlds de sus etiquetas Añade las librerías Java de Struts y los .tlds de sus etiquetas personalizadas a tu proyectopersonalizadas a tu proyecto

Configura tu web.xml para que envíe peticiones HTTP al Configura tu web.xml para que envíe peticiones HTTP al ActionServetActionServet

Configura el Configura el ActionServletActionServlet definiendo elementos < definiendo elementos <action-action-mappings>mappings> y < y <form-beans>form-beans> en en struts-config.xmlstruts-config.xml

Define tus clases Define tus clases ActionAction Define tus clases Define tus clases ActionFormActionForm Define clases adicionales Java representando la lógica de negocioDefine clases adicionales Java representando la lógica de negocio Define tus páginas de presentación JSPDefine tus páginas de presentación JSP Desplegar la aplicaciónDesplegar la aplicación La aplicación ejemplo suministrada con Struts, La aplicación ejemplo suministrada con Struts, struts-struts-

blank.warblank.war, es normalmente un buen punto de partida para , es normalmente un buen punto de partida para desarrollar una nueva aplicación usando Strutsdesarrollar una nueva aplicación usando Struts

Page 46: Arquitectura J2EE Struts

Actions en StrutsActions en Struts Se crea una acción extendiendo la clase Se crea una acción extendiendo la clase

org.apache.struts.action.Actionorg.apache.struts.action.Action El El ActionServletActionServlet ejecuta acciones invocando el método ejecuta acciones invocando el método

execute()execute() tu clase tu clase ActionAction El método El método execute()execute() contiene código para manipular el contiene código para manipular el

modelomodelo Dentro del método Dentro del método execute()execute() tienes acceso a: tienes acceso a:

Cabeceras y parámetros de peticiones HTTPCabeceras y parámetros de peticiones HTTP Atributos/beans guardados en los contextos Atributos/beans guardados en los contextos

applicationapplication//sessionsession//requestrequest scope scope Struts Struts ActionFormActionForm asociados con la acción (opcional) asociados con la acción (opcional) El El ActionMappingActionMapping associado a esta acción (opcional) associado a esta acción (opcional) El objeto El objeto httpResponsehttpResponse

El método El método execute()execute() devuelve un objeto devuelve un objeto ActionForwardActionForward que indica al que indica al ActionServletActionServlet a dónde transferir el control a a dónde transferir el control a continuacióncontinuación

Page 47: Arquitectura J2EE Struts

Form BeansForm Beans

Un ActionForm es un JavaBean con propiedades que Un ActionForm es un JavaBean con propiedades que corresponden a los controles de un formulario HTML. Los corresponden a los controles de un formulario HTML. Los parámetros son mapeados a propiedades del bean.parámetros son mapeados a propiedades del bean.

Proveen un mecanismo de buffer/validate/convert que necesitamos Proveen un mecanismo de buffer/validate/convert que necesitamos para asegurarnos que el usuario introduce los datos esperadospara asegurarnos que el usuario introduce los datos esperados

Actúa como puente entre el navegador y el objeto de negocioActúa como puente entre el navegador y el objeto de negocio El programador define un form bean extendiendo la clase El programador define un form bean extendiendo la clase

org.apache.struts.action.ActionFormorg.apache.struts.action.ActionForm (o de forma declarativa (o de forma declarativa usando usando org.apache.struts.action.DynaActionForm)org.apache.struts.action.DynaActionForm)

Hay que definir cada una de las propiedades en la clase y escribir Hay que definir cada una de las propiedades en la clase y escribir los getters/setters correspondientes, siguiendo las reglas de los getters/setters correspondientes, siguiendo las reglas de JavaBeansJavaBeans

Después de escribir el código del form bean, es necesario Después de escribir el código del form bean, es necesario asociarlo con una o más acciones a través del fichero de asociarlo con una o más acciones a través del fichero de configuración de Struts configuración de Struts struts-config.xmlstruts-config.xml

Cada vez que se llama a la acción , el Cada vez que se llama a la acción , el ActionServletActionServlet poblará las poblará las propiedades con los valores de los parámetros recibidos en el propiedades con los valores de los parámetros recibidos en el formulario HTMLformulario HTML

Las propiedades no sólo pueden ser escalares sino que también Las propiedades no sólo pueden ser escalares sino que también pueden ser colecciones de valorespueden ser colecciones de valores

Page 48: Arquitectura J2EE Struts

¿Por qué se necesitan Forms ¿Por qué se necesitan Forms Beans?Beans?

¿Por qué no simplemente se accede a los parámetros de ¿Por qué no simplemente se accede a los parámetros de una petición, en vez de usar un form bean como una petición, en vez de usar un form bean como intermediario?intermediario?

Razones:Razones: Los Form beans pueden ser validados antes de que una acción Los Form beans pueden ser validados antes de que una acción

sea invocadasea invocada Si la propiedad Si la propiedad validatevalidate de un elemento de un elemento ActionAction en el fichero en el fichero struts-config.xmlstruts-config.xml contiene el valor contiene el valor truetrue (por defecto), el (por defecto), el método método validatevalidate será invocado será invocado

Si un form bean falla en la validación puede hacer que Struts Si un form bean falla en la validación puede hacer que Struts envíe al usuario de vuelta a la vista (JSP) desde la que se envíe al usuario de vuelta a la vista (JSP) desde la que se realizó el POST en primer lugar, junto con un mensaje de errorrealizó el POST en primer lugar, junto con un mensaje de error

Es importante asignar a la propiedad Es importante asignar a la propiedad inputinput del elemento del elemento actionaction en en struts-config.xmlstruts-config.xml una referencia a la vista que entregó el una referencia a la vista que entregó el formularioformulario

Los form beans pueden ser usados por múltiples acciones o Los form beans pueden ser usados por múltiples acciones o incluso una aplicación completaincluso una aplicación completa

Si se configura al Si se configura al ActionControllerActionController para que guarde un form para que guarde un form bean en el contexto de sesión se permitirá el uso del form bean en bean en el contexto de sesión se permitirá el uso del form bean en todas las peticiones web que llegan a la aplicacióntodas las peticiones web que llegan a la aplicación

Page 49: Arquitectura J2EE Struts

Dynamic Action FormsDynamic Action Forms Son ActionForms creados de manera declarativa en Son ActionForms creados de manera declarativa en struts-struts-

config.xmlconfig.xml Una o varias propiedades dinámicas pueden ser pasadas a una Una o varias propiedades dinámicas pueden ser pasadas a una

instancia de instancia de org.apache.struts.action.DynaActionFormorg.apache.struts.action.DynaActionForm

<form-bean name=“checkoutForm” <form-bean name=“checkoutForm” type=“type=“org.apache.struts.action.DynaActionFormorg.apache.struts.action.DynaActionForm”>”> <<form-propertyform-property namename=“firstName” =“firstName” typetype=“java.lang.String”/>=“java.lang.String”/> <form-property name=“lastName” <form-property name=“lastName” type=“java.lang.String”/>type=“java.lang.String”/> <form-property name=“age” type=“java.lang.Integer” <form-property name=“age” type=“java.lang.Integer” initial=“18”/>initial=“18”/></form-bean></form-bean>

Page 50: Arquitectura J2EE Struts

Recursos de String/Manejo de Recursos de String/Manejo de ErroresErrores

Recursos de StringRecursos de String Todos los strings usados en mensajes en JSPs tanto de datos de Todos los strings usados en mensajes en JSPs tanto de datos de

aplicación como de errores puedes ser colocados en un ficheros de aplicación como de errores puedes ser colocados en un ficheros de recursos (recursos (ApplicationResources.propertiesApplicationResources.properties))

Struts proporciona etiquetas personalizadas JSP tags para acceder Struts proporciona etiquetas personalizadas JSP tags para acceder a estos recursosa estos recursos<bean:message key="prompt.goodguess.heading"/><bean:message key="prompt.goodguess.heading"/>

Manejo de erroresManejo de errores Se recomienda que el manejo de errores se lleve a cabo dentro del Se recomienda que el manejo de errores se lleve a cabo dentro del

método método execute()execute() y el control se transfiera a la vista apropiada y el control se transfiera a la vista apropiadaerrors.add("passphrase",new errors.add("passphrase",new ActionError("error.passphrase.required"));ActionError("error.passphrase.required"));

Struts proporciona un mecanismo separado para permitir la Struts proporciona un mecanismo separado para permitir la implementación de un manejador global de excepcionesimplementación de un manejador global de excepciones

Struts proporciona etiquetas JSP que ayudan en la visualización de Struts proporciona etiquetas JSP que ayudan en la visualización de los errores en tu JSP:los errores en tu JSP:<html:errors property=“passphrase”/><html:errors property=“passphrase”/>

Page 51: Arquitectura J2EE Struts

Internationalization i18nInternationalization i18n

Struts soporta internacionalización a través de ficheros de Struts soporta internacionalización a través de ficheros de recursos, sus librerías de etiquetas personalizadas y Java Localesrecursos, sus librerías de etiquetas personalizadas y Java Locales

Se pueden definir strings a visualizar en tu fichero de recursos, y Se pueden definir strings a visualizar en tu fichero de recursos, y luego ser usados en tus JSPsluego ser usados en tus JSPs

Los strings del idioma por defecto se guardan en el fichero Los strings del idioma por defecto se guardan en el fichero ApplicationResources.propertiesApplicationResources.properties

Otros ficheros de recursos adicionales pueden ser definidos que Otros ficheros de recursos adicionales pueden ser definidos que incluyen el idioma a usar en el nombre del fichero.incluyen el idioma a usar en el nombre del fichero.

Ejemplo: Ejemplo: ApplicationResources_eu.propertiesApplicationResources_eu.properties (Contiene mensajes en Euskera) (Contiene mensajes en Euskera) ApplicationResources_es.propertiesApplicationResources_es.properties (Contiene mensajes en Castellano) (Contiene mensajes en Castellano) Para cambiar el idioma preferido en IE: Para cambiar el idioma preferido en IE: ToolsToolsInternet Internet

OptionsOptionsLanguagesLanguages Los navegadores envían la cabecera HTTP Los navegadores envían la cabecera HTTP Accept-LanguageAccept-Language en en

cada petición que indica cuál es el idioma preferido por el usuariocada petición que indica cuál es el idioma preferido por el usuario Los ficheros de recursos deben colocarse en un lugar accesible Los ficheros de recursos deben colocarse en un lugar accesible

desde el desde el CLASSPATHCLASSPATH de la aplicación web, por ejemplo, debajo del de la aplicación web, por ejemplo, debajo del directorio directorio WEB-INF/classesWEB-INF/classes

Page 52: Arquitectura J2EE Struts

Ejemplo web.xml de aplicación Ejemplo web.xml de aplicación usando Strutsusando Struts

<web-app> <web-app> <!-- Action Servlet Configuration --> <!-- Action Servlet Configuration --> <servlet> <servlet>

<servlet-name><servlet-name>actionaction</servlet-name> </servlet-name> <servlet-class><servlet-class>org.apache.struts.action.ActionServletorg.apache.struts.action.ActionServlet</servlet-</servlet-

class> class> <init-param> <init-param>

<param-name>application</param-name> <param-name>application</param-name> <param-value> <param-value>

com.develop.ejsp.struts.resources.ApplicationResourcescom.develop.ejsp.struts.resources.ApplicationResources </param-value></param-value>

</init-param> </init-param> <init-param> <init-param>

<!– etc. --> <!– etc. --> </init-param> </init-param> <load-on-startup>1</load-on-startup> <load-on-startup>1</load-on-startup>

</servlet> <!-- Action Servlet Mapping --> </servlet> <!-- Action Servlet Mapping --> <<servlet-mappingservlet-mapping> >

<servlet-name><servlet-name>actionaction</servlet-name> </servlet-name> <url-pattern><url-pattern>*.do*.do</url-pattern> </url-pattern>

<</servlet-mapping/servlet-mapping> > </web-app> </web-app>

Page 53: Arquitectura J2EE Struts

Configurando StrutsConfigurando Struts

Como en toda framework se minimiza el código Como en toda framework se minimiza el código Java a escribir y se maximiza la configuración a Java a escribir y se maximiza la configuración a través de ficheros XMLtravés de ficheros XML Struts se configura a través Struts se configura a través struts-config.xmlstruts-config.xml Leído por la framework cuando arrancaLeído por la framework cuando arranca

Contiene:Contiene: Fuentes de datos (data-sources)Fuentes de datos (data-sources) Form beans, variaciones de JavaBeans. Form beans, variaciones de JavaBeans.

Ejecutan una petición basado en una entrega de un Ejecutan una petición basado en una entrega de un formulario. formulario.

Son poblados por el controlador con los datos del Son poblados por el controlador con los datos del formularioformulario

Llevan a cabo validación de datos Llevan a cabo validación de datos Son procesados por objetos Son procesados por objetos ActionAction

Global forwards y Global forwards y ActionMappings ActionMappings

Mapean el nombre de una acción a un objeto Mapean el nombre de una acción a un objeto ActionAction

Page 54: Arquitectura J2EE Struts

Ejemplo struts-config.xml IEjemplo struts-config.xml I

<struts-config> <struts-config> <<data-sourcesdata-sources>> <data-source <data-source name=“usuarios”name=“usuarios”>> <set-property property= "autoCommit" value="false"/><set-property property= "autoCommit" value="false"/>

<set-property property= "description" value="MessageBoard"/> <set-property property= "description" value="MessageBoard"/> <set-property property= "driverClass" value="..SQLServerDriver"/> <set-property property= "driverClass" value="..SQLServerDriver"/> <set-property property= "maxCount" value="4"/> <set-property property= "maxCount" value="4"/> <set-property property= "minCount" value="2"/> <set-property property= "minCount" value="2"/> <set-property property="password" value=""/> <set-property property="password" value=""/> <set-property property= "url"value="someurl"/> <set-property property= "url"value="someurl"/> <set-property property= "user" value="someuser"/> <set-property property= "user" value="someuser"/>

</data-source></data-source> </data-sources></data-sources> <!-- === Form Bean Definitions === --><!-- === Form Bean Definitions === --> <<form-beans>form-beans> <form-bean name="<form-bean name="SigninFormSigninForm" " type= "type= "com.develop.ejsp.struts.beans.SigninFormcom.develop.ejsp.struts.beans.SigninForm"/>"/> </form-beans></form-beans> <!-- === Global Forward Definitions === --><!-- === Global Forward Definitions === --> <<global-forwardsglobal-forwards>> <forward name="<forward name="signinsignin" path="" path="/signin.jsp/signin.jsp"/>"/> </global-forwards> </global-forwards>

Page 55: Arquitectura J2EE Struts

Ejemplo struts-config.xml IIEjemplo struts-config.xml II

<!-- === Action Mapping Definitions === --> <!-- === Action Mapping Definitions === --> <<action-mappingsaction-mappings> <!-- Process a user logon -->> <!-- Process a user logon --> <action path="<action path="/SigninAction/SigninAction““ type= "type= "com.develop.ejsp.struts.actions.SigninActioncom.develop.ejsp.struts.actions.SigninAction““ name="name="SigninFormSigninForm" " scope="session“scope="session“ input="/signin.jsp">input="/signin.jsp"> <forward name="<forward name="succeededsucceeded" path="/groups.jsp"/>" path="/groups.jsp"/> <forward name="<forward name="failedfailed" path="/groups.jsp"/>" path="/groups.jsp"/> </action></action> <action path="<action path="/GotoReplyToAction/GotoReplyToAction““ type= "com.develop.ejsp.struts.actions.GotoMessageAction">type= "com.develop.ejsp.struts.actions.GotoMessageAction"> <forward name="succeeded" path="/newmessage.jsp"/><forward name="succeeded" path="/newmessage.jsp"/> <forward name="failed" path="/groups.jsp"/><forward name="failed" path="/groups.jsp"/> </action></action> </action-mappings> </action-mappings> </struts-config></struts-config>

Page 56: Arquitectura J2EE Struts

Procesamiento de una petición Procesamiento de una petición en Struts Ien Struts I

Si el cliente envía la petición:Si el cliente envía la petición: http://server/app/GotoReplyToAction.dohttp://server/app/GotoReplyToAction.do

El El ActionServletActionServlet de Struts quita la extensión de Struts quita la extensión ((.do.do) y mira la acción correspondiente en el ) y mira la acción correspondiente en el fichero de configuración Struts para la acción fichero de configuración Struts para la acción GotoReplyToActionGotoReplyToAction

Si la encuentra encontrará o creará una Si la encuentra encontrará o creará una instancia del ‘tipo’ (instancia del ‘tipo’ (typetype) indicado: ) indicado: com.develop.ejsp.struts.actions.GotoMescom.develop.ejsp.struts.actions.GotoMessageActionsageAction

El método El método execute()execute() será invocado en el será invocado en el objeto objeto GotoMessageAction:GotoMessageAction: Este es el lugar donde la lógica de negocio de la Este es el lugar donde la lógica de negocio de la

petición es ejecutadapetición es ejecutada

Page 57: Arquitectura J2EE Struts

Procesamiento de petición en Procesamiento de petición en Struts IIStruts II

public class public class GotoMessageActionGotoMessageAction extends org.apache.struts.action.Action { extends org.apache.struts.action.Action {

public ActionForward execute( public ActionForward execute( ActionMapping mapping, ActionMapping mapping, ActionForm actionForm, ActionForm actionForm, HttpServletRequest request, HttpServletRequest request, HttpServletResponse response) HttpServletResponse response) throws IOException, ServletException { throws IOException, ServletException {

// lots of code omitted for clarity, but here the // lots of code omitted for clarity, but here the // business logic should be implemented // business logic should be implemented

ActionForward af = ActionForward af = mapping.findForward("succeeded"); mapping.findForward("succeeded");

return af; return af; } }

} }

Page 58: Arquitectura J2EE Struts

Procesamiento de petición en Procesamiento de petición en Struts IIIStruts III

De los cuatro parámetros recibidos en De los cuatro parámetros recibidos en execute(),execute(), ActionMappingActionMapping y y ActionFormActionForm son específicos a Strutsson específicos a Struts

El objeto El objeto ActionMappingActionMapping contiene contiene información de configuración proveniente información de configuración proveniente de de struts-config.xmlstruts-config.xml file. file.

El objeto El objeto ActionFormActionForm contiene el bean del contiene el bean del formulario que fue inicializado por el formulario que fue inicializado por el ActionServletActionServlet al procesar la petición al procesar la petición

Page 59: Arquitectura J2EE Struts

Procesamiento de petición en Procesamiento de petición en Struts IVStruts IV

En el mapeo de la acción En el mapeo de la acción GotoReplyToActionGotoReplyToAction hay hay dos posibles forward definidos:dos posibles forward definidos: Uno con el nombre "Uno con el nombre "succeededsucceeded" y otro" y otro "failed“"failed“

Si el método Si el método execute()execute() se completa sin errores el se completa sin errores el método método ActionMapping.findForward()ActionMapping.findForward() es es llamado, pasando el nombre del siguiente recurso llamado, pasando el nombre del siguiente recurso a llamar.a llamar. El método El método findForward()findForward() devuelve un objeto devuelve un objeto ActionForwardActionForward que es pasado al que es pasado al ActionServletActionServlet

El objeto El objeto ActionForwardActionForward contiene detalles de a dónde contiene detalles de a dónde debería el debería el ActionServletActionServlet enviar la petición (contiene el enviar la petición (contiene el path del JSP que va a visualizar los resultados)path del JSP que va a visualizar los resultados)

Page 60: Arquitectura J2EE Struts

Manejo de errores en Struts IManejo de errores en Struts I

Struts define la clase Struts define la clase ActionErrorsActionErrors que mantiene una colección de que mantiene una colección de objetos objetos ActionErrorActionError..

ActionErrors errors = new ActionErrors();ActionErrors errors = new ActionErrors();errors.add (ActionErrors.GLOBAL_ERROR, errors.add (ActionErrors.GLOBAL_ERROR, new ActionError("error.signing.connect"));new ActionError("error.signing.connect"));saveErrors(request,errors);saveErrors(request,errors);return (new ActionForward (mapping.findForward(“failed")));return (new ActionForward (mapping.findForward(“failed"))); El código añade un sólo objeto ActionError a la colección, pero si se El código añade un sólo objeto ActionError a la colección, pero si se

llevase a cabo validación de los campos de un formulario varios llevase a cabo validación de los campos de un formulario varios errores podrían ser mostrados.errores podrían ser mostrados.

Luego devuelve una instancia de ActionForward que redirige a Luego devuelve una instancia de ActionForward que redirige a ""failedfailed". ".

El El ActionServletActionServlet guardará en el objeto request el objeto guardará en el objeto request el objeto ActionErrorsActionErrors bajo un nombre bien conocido por Struts: bajo un nombre bien conocido por Struts:

request.setAttribute( Action.ERROR_KEY, errors);request.setAttribute( Action.ERROR_KEY, errors); Este objeto Este objeto ActionErrorsActionErrors es ahora disponible a cualquier página o es ahora disponible a cualquier página o

acción consecutiva.acción consecutiva. La página JSP “failed” anterior debería tener un área donde se La página JSP “failed” anterior debería tener un área donde se

mostrasen los errores producidos.mostrasen los errores producidos. El string usado para construir un objeto El string usado para construir un objeto ActionErrorActionError no es un no es un

mensaje de error sino que un identificador de un recurso (i18n Struts)mensaje de error sino que un identificador de un recurso (i18n Struts)

Page 61: Arquitectura J2EE Struts

Manejo de errores en Struts IIManejo de errores en Struts II

public class GotoMessageAction extends org.apache.struts.action.Action {public class GotoMessageAction extends org.apache.struts.action.Action { public ActionForward execute(ActionMapping mapping,public ActionForward execute(ActionMapping mapping, ActionForm actionForm,ActionForm actionForm, HttpServletRequest request,HttpServletRequest request, HttpServletResponse response)HttpServletResponse response)

throws IOException, ServletException {throws IOException, ServletException { ActionErrors errors = new ActionErrors();ActionErrors errors = new ActionErrors(); try {try { // business logic omitted for clarity// business logic omitted for clarity } catch(SQLException e) {} catch(SQLException e) { errors.add(ActionErrors.GLOBAL_ERROR,errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.sqlerror"));new ActionError("error.sqlerror")); }}

if (!errors.empty()) {if (!errors.empty()) { saveErrors(request, errors);saveErrors(request, errors); ActionForward af = mapping.findForward("failed");ActionForward af = mapping.findForward("failed"); return af;return af; }}

request.setAttribute(Message.MESSAGE_NAME, message);request.setAttribute(Message.MESSAGE_NAME, message); ActionForward af = mapping.findForward("succeeded");ActionForward af = mapping.findForward("succeeded"); return af;return af; }}}}

Page 62: Arquitectura J2EE Struts

Manejo de Formularios IManejo de Formularios I La otra acción definida en el fichero de configuración de Struts La otra acción definida en el fichero de configuración de Struts

era:era:<action path="/SigninAction" <action path="/SigninAction" type="com.develop.ejsp.struts. actions.SigninAction" type="com.develop.ejsp.struts. actions.SigninAction" name="SigninForm" scope="session" input="/signin.jsp"> name="SigninForm" scope="session" input="/signin.jsp">

<forward name="succeeded" path="/groups.jsp"/> <forward name="succeeded" path="/groups.jsp"/> <forward name="failed" path="/groups.jsp"/> <forward name="failed" path="/groups.jsp"/>

</action></action> Esta acción está asociada con el formulario llamado Esta acción está asociada con el formulario llamado SigningFormSigningForm, ,

también definido en el fichero de configuración:también definido en el fichero de configuración:<form-beans> <form-beans>

<form-bean name="SigninForm" <form-bean name="SigninForm" type="com.develop.ejsp.struts. beans.SigninForm"/> type="com.develop.ejsp.struts. beans.SigninForm"/> </form-beans></form-beans>

Page 63: Arquitectura J2EE Struts

Manejo de Formularios IIManejo de Formularios II Si una acción tiene un formulario asociado Si una acción tiene un formulario asociado

a ella (atributo a ella (atributo namename en action mapping), en action mapping), el el ActionServletActionServlet crea un form bean crea un form bean

Todo form bean hereda de Todo form bean hereda de org.apache.struts.action.ActionFormorg.apache.struts.action.ActionForm, , que es un JavaBean serializable. que es un JavaBean serializable.

Dos métodos en ActionForm pueden ser Dos métodos en ActionForm pueden ser sobreescritos:sobreescritos: validatevalidate() y() y resetreset()()

Page 64: Arquitectura J2EE Struts

Manejo de Formularios IIIManejo de Formularios III

public ActionErrors validate(ActionMapping mapping,public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {HttpServletRequest request) {

ActionErrors errors = new ActionErrors();ActionErrors errors = new ActionErrors();if ((username == null) || (username.length() < 1))if ((username == null) || (username.length() < 1))

errors.add ("username",errors.add ("username",new ActionError("new ActionError("error.username.requirederror.username.required"));"));

if ((password == null) || (password.length() < 1))if ((password == null) || (password.length() < 1))errors.add("password",errors.add("password",new ActionError("new ActionError("error.password.requirederror.password.required"));"));

return errors;return errors;}} El FormBean es poblado por el El FormBean es poblado por el ActionServletActionServlet con los parámetros de con los parámetros de

la petición de entrada llamando a los métodos la petición de entrada llamando a los métodos setXXX()setXXX() correspondientes. correspondientes.

Una vez poblado, el form bean es validado:Una vez poblado, el form bean es validado: Si el objeto Si el objeto ActionErrorsActionErrors devuelto es null o vacío significa que la devuelto es null o vacío significa que la

validación tuvo éxito y una instancia del form bean creado, en este caso validación tuvo éxito y una instancia del form bean creado, en este caso SigningFormSigningForm, es pasado al objeto , es pasado al objeto SigningActionSigningAction

Si la validación falla, la petición será re-direccionada por Struts a la página Si la validación falla, la petición será re-direccionada por Struts a la página que contenía el formulario inicialmente el formulario, dada por el atributo que contenía el formulario inicialmente el formulario, dada por el atributo inputinput del elemento del elemento actionaction en en struts-config.xmlstruts-config.xml

Page 65: Arquitectura J2EE Struts

Manejo de Formularios IVManejo de Formularios IV

public class SigninForm extends ActionForm {public class SigninForm extends ActionForm { String userName = null;String userName = null; String password = null;String password = null;

public SigninForm() {}public SigninForm() {} public void setUsername(String userName) {public void setUsername(String userName) {

this.userName = userName;this.userName = userName; }}

public String getUserName() {public String getUserName() { return this.userName;return this.userName; }}

public void setPassword(String password) {public void setPassword(String password) { this.password = password;this.password = password;

}}

public String getPassword() {public String getPassword() { return this.password;return this.password; }}

......

Page 66: Arquitectura J2EE Struts

Manejo de Formularios VManejo de Formularios V

// accessors and mutator omitted for clarity// accessors and mutator omitted for clarity public ActionErrors validate(ActionMapping actionMapping, public ActionErrors validate(ActionMapping actionMapping, HttpServletRequest HttpServletRequest

httpServletRequest) {httpServletRequest) { ActionErrors errors = new ActionErrors();ActionErrors errors = new ActionErrors(); if ((password == null) || (password.length() < 1)) if ((password == null) || (password.length() < 1)) errors.add("password", new errors.add("password", new

ActionError("error.password.required"));ActionError("error.password.required")); if ((userName == null) || (userName.length() < 1)) if ((userName == null) || (userName.length() < 1)) errors.add("username", new errors.add("username", new

ActionError("error.username.required"));ActionError("error.username.required")); return errors;return errors; }}

public void reset(ActionMapping actionMapping, public void reset(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {HttpServletRequest httpServletRequest) { username = "";username = ""; password="";password=""; }}}}

Page 67: Arquitectura J2EE Struts

Manejo de Formularios VIManejo de Formularios VIpublic class SigninAction public class SigninAction

extends org.apache.struts.action.Action { extends org.apache.struts.action.Action {

public ActionForward execute(ActionMapping mapping, public ActionForward execute(ActionMapping mapping, ActionForm form, ActionForm form, HttpServletRequest request, HttpServletRequest request, HttpServletResponse response) HttpServletResponse response)

throws IOException, ServletException { throws IOException, ServletException {

try { try { String username = ((SigninForm) form). getUserName(); String username = ((SigninForm) form). getUserName(); String password = ((SigninForm) form). getPassword();String password = ((SigninForm) form). getPassword(); // etc.// etc. } } }}} }

Page 68: Arquitectura J2EE Struts

DataSources en StrutsDataSources en Strutstry { try { DataSource ds = servlet.findDataSource(“usuarios”); DataSource ds = servlet.findDataSource(“usuarios”); message = new Message(); message = new Message(); message.getMessage(ds, message.getMessage(ds, request.getParameter( Message.MESSAGE_ID)),request.getParameter( Message.MESSAGE_ID)), request.getParameter( GROUP_ID_NAME)) request.getParameter( GROUP_ID_NAME)) } } El código arriba muestra otra característica de Struts, la habilidad de El código arriba muestra otra característica de Struts, la habilidad de

configurar y usar referencias a configurar y usar referencias a javax.jdbc.DataSourcesjavax.jdbc.DataSources El extracto de El extracto de struts-config.xmlstruts-config.xml anteriormente mostrado tiene una anteriormente mostrado tiene una

sección sección <data-sources><data-sources> para configurar las data sources de la aplicación. para configurar las data sources de la aplicación. Struts provee las clases Struts provee las clases GenericDataSourceGenericDataSource y y GenericConnectionGenericConnection que que

son wrappers sobre los objetos JDBC son wrappers sobre los objetos JDBC ConnectionsConnections y y DataSourcesDataSources definidos definidos en el fichero de configuración.en el fichero de configuración.

Page 69: Arquitectura J2EE Struts

Struts Tag LibrariesStruts Tag Libraries

Documentadas en Documentadas en http://www.onjava.com/lpt/a/4034http://www.onjava.com/lpt/a/4034

La framework Struts proporciona un conjunto de La framework Struts proporciona un conjunto de 6 librerías de etiquetas, que asisten en la tarea 6 librerías de etiquetas, que asisten en la tarea de la creación de la vista de MVC para evitar de la creación de la vista de MVC para evitar incluir código Java en los JSPs:incluir código Java en los JSPs: Bean Tags Bean Tags HTML Tags HTML Tags Logic Tags Logic Tags Nested Tags Nested Tags Template Tags Template Tags Tiles Tags Tiles Tags

Las funcionalidad de las etiquetas definidas en Las funcionalidad de las etiquetas definidas en las librerías las librerías BeanBean y y LogicLogic es también provista es también provista por las librerías por las librerías corecore y y fmtfmt de JSTL de JSTL Se recomienda el uso de las librerías en JSTLSe recomienda el uso de las librerías en JSTL

Page 70: Arquitectura J2EE Struts

HTML TagsHTML Tags Estas etiquetas son principalmente usadas para:Estas etiquetas son principalmente usadas para:

Crear formularios de entrada de datos yCrear formularios de entrada de datos y Otras utilidades para visualizar interfaces basados en Otras utilidades para visualizar interfaces basados en

HTML.HTML. Algunas de las acciones más útiles son:Algunas de las acciones más útiles son:

basebase genera un elemento HTML genera un elemento HTML <base><base> errorserrors condicionalmente visualiza un conjunto condicionalmente visualiza un conjunto

acumulado de mensajes de erroracumulado de mensajes de error formform define un formulario de entrada define un formulario de entrada texttext visualiza un campo de entrada de tipo texto visualiza un campo de entrada de tipo texto messagesmessages condicionalmente visualiza un conjunto de condicionalmente visualiza un conjunto de

mensajes acumuladosmensajes acumulados submitsubmit visualiza un botón de entrega visualiza un botón de entrega Etc.Etc.

Page 71: Arquitectura J2EE Struts

Logic TagsLogic Tags Usadas para:Usadas para:

Iterar sobre coleccionesIterar sobre colecciones Generación condicional de salida, y Generación condicional de salida, y Flujo de aplicaciónFlujo de aplicación

Algunas de las acciones más útiles son:Algunas de las acciones más útiles son: presentpresent genera el contenido de marcado dentro de genera el contenido de marcado dentro de

esta etiqueta si el valor indicado es encontrado en esta esta etiqueta si el valor indicado es encontrado en esta peticiónpetición

notPresentnotPresent lo opuesto a present lo opuesto a present iterateiterate repite el contenido anidado dentro de esta repite el contenido anidado dentro de esta

etiqueta al iterar sobre una colecciónetiqueta al iterar sobre una colección forwardforward transfiere control a la página especificada transfiere control a la página especificada

por la entrada por la entrada ActionForwardActionForward. . Etc.Etc.

Page 72: Arquitectura J2EE Struts

Tiles Tags (Framework)Tiles Tags (Framework)

La librería de etiquetas Tiles es un super-conjunto de la La librería de etiquetas Tiles es un super-conjunto de la librería Templateslibrería Templates

Intenta evitar la duplicación de contenido de lenguaje Intenta evitar la duplicación de contenido de lenguaje de marcado dentro de una aplicación web con respecto de marcado dentro de una aplicación web con respecto al look-and-feel de un portal:al look-and-feel de un portal: Un mecanismo normalmente utilizado es usar la directiva Un mecanismo normalmente utilizado es usar la directiva

jsp:includejsp:include para añadir cabeceras/menús y pies de para añadir cabeceras/menús y pies de páginas a un portal webpáginas a un portal web

Tiles reduce el tamaño de código redundante en una Tiles reduce el tamaño de código redundante en una aplicación web y separa el contenido de la visualización aplicación web y separa el contenido de la visualización del mismo de manera más eficiente del mismo de manera más eficiente Tiles define Tiles define Layout ManagersLayout Managers para JSPs para JSPs

Su objetivo principal es evitar en los JSPs contenido de Su objetivo principal es evitar en los JSPs contenido de marcado que corresponda con el layout del portal marcado que corresponda con el layout del portal factoriza este marcado, de tal manera que la factoriza este marcado, de tal manera que la modificación del layout sea sencilla y eficientemodificación del layout sea sencilla y eficiente

Page 73: Arquitectura J2EE Struts

JSP TemplatesJSP Templates

Un template es una página JSP que usa Un template es una página JSP que usa una librería de etiquetas una librería de etiquetas personalizadas para describir la personalizadas para describir la disposición (layout) de los disposición (layout) de los componentes de la páginacomponentes de la página Define cómo aparecerán las páginas JSP de Define cómo aparecerán las páginas JSP de

una aplicación, sin especificar el contenidouna aplicación, sin especificar el contenido Esta definición es utilizada por todos los Esta definición es utilizada por todos los

JSPs sin necesidad de mezclar layout con JSPs sin necesidad de mezclar layout con contenidocontenido

Page 74: Arquitectura J2EE Struts

Ejemplo Tiles: index.jsp IEjemplo Tiles: index.jsp I

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %><%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %><%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %><%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<html:html><html:html><head><head><title><bean:message key="global.title"/></title><title><bean:message key="global.title"/></title><html:base/><html:base/><script language=javascript src="include/scripts.js"></script><script language=javascript src="include/scripts.js"></script><link rel="stylesheet" href="stylesheets/format_win_nav_main.css" <link rel="stylesheet" href="stylesheets/format_win_nav_main.css"

type="text/css">type="text/css"></head></head>

<body topmargin="0" leftmargin="0" bgcolor="#FFFFFF"><body topmargin="0" leftmargin="0" bgcolor="#FFFFFF">

<!-- Header Page Information --><!-- Header Page Information --><%@ include file="include/head.inc"%><%@ include file="include/head.inc"%>

<!-- Nav Bar --><!-- Nav Bar --><%@ include file="include/menubar.inc"%><%@ include file="include/menubar.inc"%>

Page 75: Arquitectura J2EE Struts

Ejemplo Tiles: index.jsp IIEjemplo Tiles: index.jsp II

<%@ include file="include/mainoffer.inc"%><%@ include file="include/mainoffer.inc"%><!-- Featured Items Header Row --><!-- Featured Items Header Row --><table width="645" cellpadding="0" cellspacing="0" border="0"><table width="645" cellpadding="0" cellspacing="0" border="0"> <tr> <tr> <td width="21"><html:img height="1" alt="" page="/images/spacer.gif" width="1" <td width="21"><html:img height="1" alt="" page="/images/spacer.gif" width="1"

border="0"/></td>border="0"/></td> <td width="534"><html:img page="/images/week_picks.gif" <td width="534"><html:img page="/images/week_picks.gif"

altKey="label.featuredproducts"/></td>altKey="label.featuredproducts"/></td> <td width="1" bgcolor="#9E9EFF"><html:img height="1" alt="" page="/images/spacer.gif" <td width="1" bgcolor="#9E9EFF"><html:img height="1" alt="" page="/images/spacer.gif"

width="1" border="0"/></td>width="1" border="0"/></td> <td width="1" bgcolor="#9E9EFF"><html:img height="1" alt="" <td width="1" bgcolor="#9E9EFF"><html:img height="1" alt=""

page="/images/spacer.gif" width="1" border="0"/></td>page="/images/spacer.gif" width="1" border="0"/></td> <td width="90" bgcolor="#9E9EFF" align="right"><html:img height="1" alt="" <td width="90" bgcolor="#9E9EFF" align="right"><html:img height="1" alt=""

page="/images/spacer.gif" width="90" border="0"/></td>page="/images/spacer.gif" width="90" border="0"/></td> </tr></tr> <tr><tr> <td><html:img height="1" alt="" page="/images/spacer.gif" width="21" <td><html:img height="1" alt="" page="/images/spacer.gif" width="21"

border="0"/></td>border="0"/></td> <td colspan="4" bgcolor="#9E9EFF"><html:img height="1" alt="" <td colspan="4" bgcolor="#9E9EFF"><html:img height="1" alt=""

page="/images/spacer.gif" width="1" border="0"/></td>page="/images/spacer.gif" width="1" border="0"/></td> </tr></tr></table></table><html:img height="10" alt="" page="/images/spacer.gif" width="1" border="0"/><br><html:img height="10" alt="" page="/images/spacer.gif" width="1" border="0"/><br><!-- THIS WEEK'S FEATURES --><!-- THIS WEEK'S FEATURES --><%@ include file="include/featureditems.inc"%><%@ include file="include/featureditems.inc"%><%@ include file="include/copyright.inc"%><%@ include file="include/copyright.inc"%></body></body></html:html></html:html>

Page 76: Arquitectura J2EE Struts

Ejemplo Tiles: Ejemplo Tiles: storefront storefront DefaultLayout.jspDefaultLayout.jsp

<%@ taglib uri=“/WEB-INF/struts-html.tld” prefix=“html” %><%@ taglib uri=“/WEB-INF/struts-html.tld” prefix=“html” %><%@ taglib uri=“/WEB-INF/struts-bean.tld” prefix=“bean” %><%@ taglib uri=“/WEB-INF/struts-bean.tld” prefix=“bean” %><%@ taglib uri=“/WEB-INF/tiles.tld” prefix=“tiles” %><%@ taglib uri=“/WEB-INF/tiles.tld” prefix=“tiles” %><html:html><html:html>

<head><head><title><title><bean:message key=“global.title”/><bean:message key=“global.title”/></title></title><html:base/><html:base/>

</head></head><body topmargin=“0” leftmargin=“0” bgcolor=“#FFFFFF”><body topmargin=“0” leftmargin=“0” bgcolor=“#FFFFFF”>

<tiles:insert attribute=“header”/><tiles:insert attribute=“header”/><tiles:insert attribute=“menubar”/><tiles:insert attribute=“menubar”/><tiles:insert attribute=“body-content”/><tiles:insert attribute=“body-content”/><tiles:insert attribute=“copyright”/><tiles:insert attribute=“copyright”/>

</body></body></html:html></html:html>

Page 77: Arquitectura J2EE Struts

Ejemplo Tiles: Ejemplo Tiles: storefront-storefront-defs.jspdefs.jsp

<%@ taglib uri=“/WEB-INF/tiles.tld” prefix=“tiles” %><%@ taglib uri=“/WEB-INF/tiles.tld” prefix=“tiles” %><<tiles:definitiontiles:definition

id=“storefront.default”id=“storefront.default”page=“/layouts/storefrontDefaultLayout.jsp”page=“/layouts/storefrontDefaultLayout.jsp”scope=“request”>scope=“request”>

<tiles:put name=“header” <tiles:put name=“header” value=“/common/header.jsp”/>value=“/common/header.jsp”/>

<tiles:put name=“menubar” <tiles:put name=“menubar” value=“/common/menubar.jsp”/>value=“/common/menubar.jsp”/>

<tiles:put name=“copyright” <tiles:put name=“copyright” value=“/common/copyright.jsp”/>value=“/common/copyright.jsp”/>

</tiles:definition></tiles:definition>

Page 78: Arquitectura J2EE Struts

Ejemplo Tiles: Ejemplo Tiles: index.jspindex.jsp

<%@ taglib uri=“/WEB-INF/tiles.tld” prefix=“tiles” %><%@ taglib uri=“/WEB-INF/tiles.tld” prefix=“tiles” %><%@ include file=“../common/storefront-defs.jsp” %><%@ include file=“../common/storefront-defs.jsp” %>

<<tiles:inserttiles:insert beanName=“storefront.default” beanName=“storefront.default” beanScope=“request”>beanScope=“request”>

<<tiles:put name=“body-content” tiles:put name=“body-content” value=“index-body.jsp”/>value=“index-body.jsp”/></tile:insert> </tile:insert>

Para más información sobre Tiles Framework ir a:Para más información sobre Tiles Framework ir a: http://www.lifl.fr/http://www.lifl.fr/~~dumoulin/tiles/index.htmldumoulin/tiles/index.html

Para instalar Tiles en Struts es necesario añadir una sección Para instalar Tiles en Struts es necesario añadir una sección plug-inplug-in en en struts-config.xmlstruts-config.xml para la clase: para la clase: org.apache.struts.tiles.TilesPluginorg.apache.struts.tiles.TilesPlugin

Page 79: Arquitectura J2EE Struts

Mi primera aplicación con Mi primera aplicación con Apache StrutsApache Struts

Aplicación para llevar a cabo loginAplicación para llevar a cabo login Una vez que el usuario ha hecho login las Una vez que el usuario ha hecho login las

páginas cambian para indicar tal circunstanciapáginas cambian para indicar tal circunstancia Consiste de dos pantallas:Consiste de dos pantallas:

Página Página WelcomeWelcome que saluda al usario y ofrece enlaces que saluda al usario y ofrece enlaces a la aplicacióna la aplicación

Página Página LogonLogon que permite al usuario introducir que permite al usuario introducir username y passwordusername y password

Esta página lleva a cabo la validación que los datos Esta página lleva a cabo la validación que los datos introducidos son correctosintroducidos son correctos

Page 80: Arquitectura J2EE Struts

Welcome.htmlWelcome.html

<HTML><HTML><HEAD><HEAD><TITLE>Welcome World!!</TITLE><TITLE>Welcome World!!</TITLE><base <base

href="http://localhost:8080/logon/pages/Welcome.jsp">href="http://localhost:8080/logon/pages/Welcome.jsp"></HEAD></HEAD><BODY><BODY><H3>Welcome World!</H3><H3>Welcome World!</H3><UL><UL><LI><a href="/logon/logon.do">Sign in</a></LI><LI><a href="/logon/logon.do">Sign in</a></LI></UL></UL><IMG src='struts-power.gif' alt='Powered by Struts'><IMG src='struts-power.gif' alt='Powered by Struts'></BODY></BODY></HTML></HTML>

Page 81: Arquitectura J2EE Struts

Welcome.jsp IWelcome.jsp I

<%@ taglib uri="/tags/struts-bean" prefix="bean" %><%@ taglib uri="/tags/struts-bean" prefix="bean" %><%@ taglib uri="/tags/struts-html" prefix="html" %><%@ taglib uri="/tags/struts-html" prefix="html" %><%@ taglib uri="/tags/struts-logic" prefix="logic" %><%@ taglib uri="/tags/struts-logic" prefix="logic" %><HTML><HTML><HEAD><HEAD><TITLE>Welcome World!!</TITLE><TITLE>Welcome World!!</TITLE><html:base/><html:base/></HEAD></HEAD><BODY><BODY><<logic:presentlogic:present name="user"> name="user"><H3>Welcome <<H3>Welcome <bean:writebean:write name="user" property="username"/>!</H3> name="user" property="username"/>!</H3></logic:present></logic:present><<logic:notPresentlogic:notPresent scope="session" name="user"> scope="session" name="user"><H3>Welcome World!</H3><H3>Welcome World!</H3></logic:notPresent></logic:notPresent><html:errors/><html:errors/><UL><UL><LI><<LI><html:linkhtml:link forward="logon">Sign in</html:link></LI> forward="logon">Sign in</html:link></LI><logic:present name="user"><logic:present name="user"><LI><<LI><html:linkhtml:link forward="logoff">Sign out</html:link></LI> forward="logoff">Sign out</html:link></LI></logic:present></logic:present></UL></UL><IMG src='struts-power.gif' alt='Powered by Struts'><IMG src='struts-power.gif' alt='Powered by Struts'></BODY></BODY></HTML></HTML>

Page 82: Arquitectura J2EE Struts

Welcome.jsp IIWelcome.jsp II <html:base/><html:base/> garantiza que referencias a imágenes o otros garantiza que referencias a imágenes o otros

recursos son relativas a la localización del JSPrecursos son relativas a la localización del JSP<<logic:presentlogic:present name="user"> name="user">

<H3>Welcome <<H3>Welcome <bean:writebean:write name="user" name="user" property="username"/>!</H3>property="username"/>!</H3>

</logic:present></logic:present> Esta etiqueta personalizada asegura que el usuario solamente es Esta etiqueta personalizada asegura que el usuario solamente es

saludado si ha efectuado loginsaludado si ha efectuado login <logic:notPresent> tiene el comportamiento opuesto<logic:notPresent> tiene el comportamiento opuesto<LI><<LI><html:linkhtml:link forward="logon">Sign in</html:link></LI> forward="logon">Sign in</html:link></LI> Struts reescribe automáticamente los enlaces para mantener la Struts reescribe automáticamente los enlaces para mantener la

sesión del usuario. También permite dar a los enlaces un nombre sesión del usuario. También permite dar a los enlaces un nombre lógico y luego guardar los enlaces reales en un fichero de lógico y luego guardar los enlaces reales en un fichero de configuración.configuración.

Page 83: Arquitectura J2EE Struts

Logon.htmlLogon.html

<HTML><HTML><HEAD><HEAD><TITLE>Sign in, Please!</TITLE><TITLE>Sign in, Please!</TITLE></HEAD></HEAD><BODY><BODY><form name="logonForm" method="POST" action="/logon/LogonSubmit.do"><form name="logonForm" method="POST" action="/logon/LogonSubmit.do"><TABLE border="0" width="100%"><TABLE border="0" width="100%"><TR><TR><TH align="right">Username:</TH><TH align="right">Username:</TH><TD align="left"><input type="text" name="username" value=""></TD><TD align="left"><input type="text" name="username" value=""></TD></TR></TR><TR><TR><TH align="right">Password:</TH><TH align="right">Password:</TH><TD align="left"><input type="password" name="password" value=""></TD><TD align="left"><input type="password" name="password" value=""></TD></TR></TR><TR><TR><TD align="right"><input type="submit" name="submit" value="Submit"></TD><TD align="right"><input type="submit" name="submit" value="Submit"></TD><TD align="left"><input type="reset" name="reset" value="Reset"></TD><TD align="left"><input type="reset" name="reset" value="Reset"></TD></TR></TR></TABLE></TABLE></form></form><script language="JavaScript" type="text/javascript"><script language="JavaScript" type="text/javascript"><!--<!--document.forms["logonForm"].elements["username"].focus()document.forms["logonForm"].elements["username"].focus()// -->// --></script></script></BODY></BODY></HTML></HTML>

Page 84: Arquitectura J2EE Struts

Logon.jsp ILogon.jsp I

<%@ taglib uri="/tags/struts-html" prefix="html" %><%@ taglib uri="/tags/struts-html" prefix="html" %><HTML><HTML><HEAD><HEAD><TITLE>Sign in, Please!</TITLE><TITLE>Sign in, Please!</TITLE></HEAD></HEAD><BODY><BODY><<html:errorshtml:errors/>/><<html:formhtml:form action="/LogonSubmit" focus="username"> action="/LogonSubmit" focus="username"><TABLE border="0" width="100%"><TABLE border="0" width="100%"><TR><TR><TH align="right">Username:</TH><TH align="right">Username:</TH><TD align="left"><<TD align="left"><html:texthtml:text property="username"/></TD> property="username"/></TD></TR></TR><TR><TR><TH align="right">Password:</TH><TH align="right">Password:</TH><TD align="left"><<TD align="left"><html:passwordhtml:password property="password"/></TD> property="password"/></TD></TR></TR><TR><TR><TD align="right"><<TD align="right"><html:submithtml:submit/></TD>/></TD><TD align="left"><<TD align="left"><html:resethtml:reset/></TD>/></TD></TR></TR></TABLE></TABLE></html:form></html:form></BODY></BODY></HTML></HTML>

Page 85: Arquitectura J2EE Struts

Logon.jsp IILogon.jsp II

<%@ taglib uri="/tags/struts-html" prefix="html"%><%@ taglib uri="/tags/struts-html" prefix="html"%> La librería de etiquetas html definida por Struts es La librería de etiquetas html definida por Struts es

disponible a la páginadisponible a la página <<html:errorshtml:errors/> /> garantiza si ha habido algún error durante garantiza si ha habido algún error durante

el login, que estos errores sean visualizadosel login, que estos errores sean visualizados<<html:formhtml:form action="/LogonSubmit" focus="username"> action="/LogonSubmit" focus="username"> Produce un formulario HTML para la entrada de datos. Produce un formulario HTML para la entrada de datos.

También genera JavaScript para mover el cursor al campo También genera JavaScript para mover el cursor al campo usernameusername del formulario del formulario La propiedad La propiedad actionaction hace referencia a un componente hace referencia a un componente

ActionMappingActionMapping en el fichero de configuración de Struts en el fichero de configuración de Struts dice dice al formulario que JavaBean (derivado de al formulario que JavaBean (derivado de ActionFormActionForm) debe ) debe usar para poblar los controles de HTML.usar para poblar los controles de HTML.

Page 86: Arquitectura J2EE Struts

Logon.jsp IIILogon.jsp III

<<html:texthtml:text property="username"/> property="username"/> Crea un control de entrada HTML para un campo Crea un control de entrada HTML para un campo

de texto. Asignará a este campo la propiedad de texto. Asignará a este campo la propiedad usernameusername del JavaBean de ayuda antes del JavaBean de ayuda antes mencionado.mencionado.

<html:password> crea un campo de entrada<html:password> crea un campo de entrada <html:submit> y <html:reset> generan botones <html:submit> y <html:reset> generan botones

HTML Submit y Reset. Dos objetos serán HTML Submit y Reset. Dos objetos serán invocados cuando se usen estos botones:invocados cuando se usen estos botones: ActionFormActionForm ActionAction

Page 87: Arquitectura J2EE Struts

Configuración de la acción Configuración de la acción logon Ilogon I

Configuración para la pantalla de Configuración para la pantalla de logon:logon: JSP hace referencia al JSP hace referencia al /LogonSubmit/LogonSubmit ActionMappingActionMapping

ActionMappingActionMapping hace referencia a los hace referencia a los objetos:objetos:

app.LogonFormapp.LogonForm describe propiedades describe propiedades usadas por el formulario logonusadas por el formulario logon

app.LogonActionapp.LogonAction lleva a cabo el lleva a cabo el procesamiento del formularioprocesamiento del formulario

Page 88: Arquitectura J2EE Struts

Configuración de la acción Configuración de la acción logon IIlogon II

<html:form action="/LogonSubmit" focus="username"><html:form action="/LogonSubmit" focus="username"> La configuración asociada al atributo acción en Struts sería:La configuración asociada al atributo acción en Struts sería:<action path="/LogonSubmit"<action path="/LogonSubmit" type="app.LogonAction"type="app.LogonAction" name="logonForm"name="logonForm" scope="request"scope="request" validate="true"validate="true" input="/pages/Logon.jsp"/>input="/pages/Logon.jsp"/> pathpath identicador único para el mapping identicador único para el mapping typetype acción a invocar cuando el formulario es entregado acción a invocar cuando el formulario es entregado namename el helper JavaBean (ActionForm) a usarse con el formulario el helper JavaBean (ActionForm) a usarse con el formulario

HTMLHTML scopescope indica en qué contexto debe guardarse el indica en qué contexto debe guardarse el ActionFormActionForm validatevalidate indica si es necesario invocar al método indica si es necesario invocar al método validatevalidate del del

ActionFormActionForm antes de invocar al objeto antes de invocar al objeto ActionAction input input indica a donde ir si indica a donde ir si validatevalidate devuelve falso devuelve falso<form-bean name="logonForm"<form-bean name="logonForm" type="app.LogonForm"/>type="app.LogonForm"/> Este extracto del fichero de configuración relaciona el nombre lógico Este extracto del fichero de configuración relaciona el nombre lógico

logonFormlogonForm con la clase con la clase app.LogonFormapp.LogonForm

Page 89: Arquitectura J2EE Struts

LogonForm: un ejemplo de un LogonForm: un ejemplo de un ActionFormActionForm

public ActionErrors validate(ActionMapping mapping,public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {HttpServletRequest request) {

ActionErrors errors = new ActionErrors();ActionErrors errors = new ActionErrors();if ((username == null) || (username.length() < 1))if ((username == null) || (username.length() < 1))

errors.add ("username",errors.add ("username",new ActionError("new ActionError("error.username.requirederror.username.required"));"));

if ((password == null) || (password.length() < 1))if ((password == null) || (password.length() < 1))errors.add("password",errors.add("password",new ActionError("new ActionError("error.password.requirederror.password.required"));"));

return errors;return errors;}} Si validate no devuelve null, entonces el Si validate no devuelve null, entonces el ActionControllerActionController servlet servlet

guardará el objeto guardará el objeto ActionErrorsActionErrors devuelto en el contexto request, devuelto en el contexto request, bajo una clave conocida por la etiqueta bajo una clave conocida por la etiqueta html:errorshtml:errors

Los tokens Los tokens error.username.requirederror.username.required y y error.password.requirederror.password.required son claves que son utilizadas para mirar los strings correspondientes son claves que son utilizadas para mirar los strings correspondientes en el fichero de recursos de Strutsen el fichero de recursos de Struts

Recordar que cada Locale contiene su propio fichero de recursos lo que Recordar que cada Locale contiene su propio fichero de recursos lo que hace que los mensajes sean fácilmente localizables.hace que los mensajes sean fácilmente localizables.

Page 90: Arquitectura J2EE Struts

LogonAction: un ejemplo de un LogonAction: un ejemplo de un LogonAction ILogonAction I

package app;package app;import java.io.IOException;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.Action;import org.apache.struts.action.Action;import org.apache.struts.action.ActionError;import org.apache.struts.action.ActionError;import org.apache.struts.action.ActionErrors;import org.apache.struts.action.ActionErrors;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.action.ActionMapping;import org.apache.struts.action.ActionServlet;import org.apache.struts.action.ActionServlet;

public final class LogonAction extends Action {public final class LogonAction extends Action {// Validate credentials with business tier// Validate credentials with business tierpublic boolean isUserLogon (String username,public boolean isUserLogon (String username,

String password) throws UserDirectoryException {String password) throws UserDirectoryException {return (UserDirectory.getInstance().isValidPassword(username,password));return (UserDirectory.getInstance().isValidPassword(username,password));

} // end isUserLogon} // end isUserLogon

Page 91: Arquitectura J2EE Struts

LogonAction: un ejemplo de un LogonAction: un ejemplo de un LogonAction IILogonAction II

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)HttpServletResponse response)throws IOException, ServletException {throws IOException, ServletException {// Obtain username and password from web tier// Obtain username and password from web tierString username = ((LogonForm) form).getUsername();String username = ((LogonForm) form).getUsername();String password = ((LogonForm) form).getPassword();String password = ((LogonForm) form).getPassword();// Validate credentials// Validate credentialsboolean validated = false;boolean validated = false;try {try { validated = isUserLogon(username,password);validated = isUserLogon(username,password);} catch (UserDirectoryException ude) {} catch (UserDirectoryException ude) { // couldn't connect to user directory// couldn't connect to user directory ActionErrors errors = new ActionErrors();ActionErrors errors = new ActionErrors();

errors.add (ActionErrors.GLOBAL_ERROR, new ActionError("error.logon.connect"));errors.add (ActionErrors.GLOBAL_ERROR, new ActionError("error.logon.connect")); saveErrors(request,errors);saveErrors(request,errors); // return to input page// return to input page return (new ActionForward (mapping.getInput()));return (new ActionForward (mapping.getInput()));

}}// Save our logged-in user in the session, because we use it again later.// Save our logged-in user in the session, because we use it again later.HttpSession session = request.getSession();HttpSession session = request.getSession();session.setAttribute(Constants.USER_KEY, form);session.setAttribute(Constants.USER_KEY, form);// Log this event, if appropriate// Log this event, if appropriateif (servlet.getDebug() >= Constants.DEBUG) {if (servlet.getDebug() >= Constants.DEBUG) { StringBuffer message = new StringBuffer("LogonAction: User '");StringBuffer message = new StringBuffer("LogonAction: User '"); message.append(username);message.append(username);

message.append("' logged on in session ");message.append("' logged on in session "); message.append(session.getId());message.append(session.getId()); servlet.log(message.toString);servlet.log(message.toString);

}}// Return success// Return success

return (mapping.findForward (Constants.WELCOME));return (mapping.findForward (Constants.WELCOME));} // end perform} // end perform} // end LogonAction} // end LogonAction

Page 92: Arquitectura J2EE Struts

LogonAction: un ejemplo de un LogonAction: un ejemplo de un LogonAction IIILogonAction III

// Validate credentials// Validate credentialsboolean validated = false;boolean validated = false;try {try {

validated = isUserLogon(username,password);validated = isUserLogon(username,password);} catch (UserDirectoryException ude) {} catch (UserDirectoryException ude) {

// couldn't connect to user directory// couldn't connect to user directoryActionErrors errors = new ActionErrors();ActionErrors errors = new ActionErrors();errors.add (ActionErrors.GLOBAL_ERROR, errors.add (ActionErrors.GLOBAL_ERROR,

new ActionError("error.logon.connect"));new ActionError("error.logon.connect")); saveErrors(request,errors);saveErrors(request,errors); // return to input page// return to input page return (new ActionForward(mapping.getInput()));return (new ActionForward(mapping.getInput()));}} Si un error es encontrado mientras se lleva a cabo la validación de la entrada del Si un error es encontrado mientras se lleva a cabo la validación de la entrada del

usuario y una excepción es lanzada, entonces el error es transformado en un usuario y una excepción es lanzada, entonces el error es transformado en un ActionErrorActionError y el control es devuelto a la página de entrada. Lo mismo se lleva a y el control es devuelto a la página de entrada. Lo mismo se lleva a cabo si se puede contactar al servicio de directorio pero el login del usuario no es cabo si se puede contactar al servicio de directorio pero el login del usuario no es correctocorrecto

return (mapping.findForward (Constants.WELCOME));return (mapping.findForward (Constants.WELCOME)); Un objeto de tipo ActionForward será devuelto al ActionServlet si todo va bien. En Un objeto de tipo ActionForward será devuelto al ActionServlet si todo va bien. En

este caso se envía control al forward success declarado en el fichero de este caso se envía control al forward success declarado en el fichero de configuración como:configuración como:

<forward name=“success”<forward name=“success” path=“/pages/Welcome.jsp”/>path=“/pages/Welcome.jsp”/>

Page 93: Arquitectura J2EE Struts

Modificaciones a realizar en Modificaciones a realizar en guessingguessing

1.1. Modificar action /guess en struts-config.xml, haciendo que esa Modificar action /guess en struts-config.xml, haciendo que esa acción esté asociada a la clase acción esté asociada a la clase es.deusto.guessing.action.GuessingAction y al formulario es.deusto.guessing.action.GuessingAction y al formulario es.deusto.guessing.form.GuessingForm. es.deusto.guessing.form.GuessingForm.

2.2. Asegurarse que existe correspondencia entre clase guessing.jsp Asegurarse que existe correspondencia entre clase guessing.jsp y GuessingForm y GuessingForm

3.3. Asegurarse que un usuario después de haber hecho login pueda Asegurarse que un usuario después de haber hecho login pueda jugar una partida, el usuario podrá realizar intentos jugar una partida, el usuario podrá realizar intentos infinitamente, pero esos intentos hay que contabilizarlos y infinitamente, pero esos intentos hay que contabilizarlos y visualizarlos cada vez que el usuario falla o adivina el númerovisualizarlos cada vez que el usuario falla o adivina el número

4.4. El número a adivinar es asociado a la sesión del usuario y El número a adivinar es asociado a la sesión del usuario y generado la primera vez que la acción execute se ejecuta para generado la primera vez que la acción execute se ejecuta para un usuarioun usuario

5.5. Idealmente crear una clase llamada Game que contenga el Idealmente crear una clase llamada Game que contenga el número a adivinar y el número de intentos fallidosnúmero a adivinar y el número de intentos fallidos

6.6. Modificar la aplicación de manera que nuevos usuarios puedan Modificar la aplicación de manera que nuevos usuarios puedan ser definidos y los datos de login de esos usuarios se salven en ser definidos y los datos de login de esos usuarios se salven en un fichero .properties.un fichero .properties.

Page 94: Arquitectura J2EE Struts

Más EjemplosMás Ejemplos

Para más ejemplos del uso de Struts Para más ejemplos del uso de Struts visitar:visitar: http://struts.sourceforge.net/http://struts.sourceforge.net/

Page 95: Arquitectura J2EE Struts

Especificaciones de las Especificaciones de las tecnologías J2EEtecnologías J2EE

1.1. Java™ 2 Platform, Enterprise Edition Specification, Version 1.4 Java™ 2 Platform, Enterprise Edition Specification, Version 1.4 (J2EE specification)(J2EE specification)..

2.2. Java™ API for XML-Based RPC Specification, Version 1.1 (Java™ API for XML-Based RPC Specification, Version 1.1 (JAXP specification).JAXP specification).

3.3. Java™ API for XML Processing Specification, Version 1.2 (Java™ API for XML Processing Specification, Version 1.2 (JAXP specification)JAXP specification)..

4.4. SOAP with Attachments API for Java Specification, Version 1.2 SOAP with Attachments API for Java Specification, Version 1.2 (SAAJ (SAAJ specification).specification).

5.5. Java API for XML Registries Specification, Version 1.0 Java API for XML Registries Specification, Version 1.0 (JAXR (JAXR specification). specification).

6.6. Web Services for J2EE Specification, Version 1.1Web Services for J2EE Specification, Version 1.1..7.7. Java API for XML Binding Specification Java API for XML Binding Specification (JAXB specification).(JAXB specification).8.8. Java™ Servlet Specification, Version 2.4 Java™ Servlet Specification, Version 2.4 (Servlet specification).(Servlet specification).9.9. JavaServer Pages™ Specification, Version 2.0 JavaServer Pages™ Specification, Version 2.0 (JSP specification).(JSP specification).10.10. Enterprise JavaBeans™ Specification, Version 2.1 Enterprise JavaBeans™ Specification, Version 2.1 (EJB specification).(EJB specification).11.11. J2EE™ Connector Architecture Specification, Version 1.5 (J2EE™ Connector Architecture Specification, Version 1.5 (Connector Connector

specification).specification).12.12. Java™ Message Service Specification, Version 1.0.2 Java™ Message Service Specification, Version 1.0.2 (JMS specification).(JMS specification).

Page 96: Arquitectura J2EE Struts

Herramientas J2EE Herramientas J2EE SUN Microsystems Developer SUN Microsystems Developer

NetworkNetwork XML Sun Developer NetworkXML Sun Developer Network Java API for XML Processing (JAXP) Java API for XML Processing (JAXP) Java API for XML Registries (JAXR) Java API for XML Registries (JAXR) Java API for XML-based RPC (JAX-RPC) Java API for XML-based RPC (JAX-RPC) Java Architecture for XML Binding (JAXB) Java Architecture for XML Binding (JAXB)

Introducción a JAXB con NetBeansIntroducción a JAXB con NetBeans SOAP with Attachments API for Java (SAAJ)SOAP with Attachments API for Java (SAAJ) The J2EE 1.4 Tutorial for NetBeans IDE The J2EE 1.4 Tutorial for NetBeans IDE

4.14.1