Tema 4 - Apache Jakarta Struts

Dr. Diego Lz. de Ipiña Gz. de Artaza http://paginaspersonales.deusto.es/dipina http://paginaspersonales.deusto.es/dipina/cursos/J2EECesine.zip dipina@eside.deusto.es

Contenido 


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


Instalación Flujo de control en Struts 
 

Procesamiento de peticiones Control de errores Manejo de Formularios 



Librerías de etiquetas de Struts Internacionalización 



Ejemplo de aplicación Struts Java Server Faces

Modelos de desarrollo de aplicaciones web en Java 
  

Los servlets son buenos ejecutando lógica de negocio, pero no son tan buenos presentando información JSPs son muy buenos presentando pero pésimos introduciendo lógica programática en ellos La combinación Servlet/JSPs es lo más común hoy en día en el desarrollo de aplicaciones web Dos arquitecturas:  

Model-1: JSPs para presentación y control y JavaBeans para la lógica Model-2: Model-View-Controller = JavaBeans-JSPs-Servlets 

MVC es tan común que se han desarrollado varias infraestructuras en torno a este patrón de diseño: 


Apache Struts Java Server Faces

Arquitectura Model 1 .

Arquitectura Model 2 .

Modelo MVC 0 .

la sesión o la aplicación Servlet transfiere control a un JSP que lleva a cabo la presentación de resultados . procesa URL recibida y delega procesamiento a JavaBeans Servlet guarda resultado de procesamiento realizado por JavaBeans en el contexto de la petición.Modelo MVC I  El Controlador (Controller)    Servlet central recibe peticiones.

. 2.Modelo MVC II   El Modelo (Model) JavaBeans (o EJBs para aplicaciones más escalables) desempeña el rol de modelo:   Algunos beans ejecutan lógica Otros guardan datos Servlet controlador invoca un método en bean lógico y éste devuelve un bean de datos Autor de JSP tiene acceso a bean de datos  Normalmente: 1.

Modelo MVC III  La Vista (View)    Rol ejecutado por JSPs Servlet Controlador transfiere control al JSP después de haber guardado en un contexto el resultado en forma de un bean de datos JSP usa jsp:useBean y jsp:getProperty para recuperar datos y formatear respuesta en HTML o XML .

Modelo MVC IV  En resumen:    Los beans o EJBs ejecutan la lógica de negocio y guardan los resultados Los JSPs proveen la información formateada Los servlets coordinan/controlan la ejecución de los beans y los JSPs .

Frameworks   Las frameworks pueden ser vistas como implementaciones de patrones de diseño que facilitan la reutilización de diseño y código Dado que MVC ha sido utilizado en muchas aplicaciones web. el desarrollo de frameworks que den soporte a áreas comunes en todas las aplicaciones MVC es necesario  Apache Struts es una de estas frameworks Código Java Deployment descriptors que configuran la framework para el uso de nuestra aplicación  Aplicaciones basadas en Struts consistirán de:   .

Apache Jakarta Struts   Implementación del modelo 2/patrón de diseño MVC que facilita la creación de aplicaciones web en Java Creada por Craig McClanahan y donada a la Apache Software Foundation en el 2000 (pertenece a Apache Jakarta) .

. .¿Qué proporciona Struts?   Un servlet (ActionServlet) que actúa como controlador MVC totalmente configurable Clases base que son extendidas para implementar la lógica de la aplicación web:   Struts Action Struts ActionForm       Un rico conjunto de etiquetas personalizadas JSP que cooperan con el controlador para su uso en la capa view de MVC Varias opciones para la validación de entrada de usuario en formularios HTML: ActionForm o Validator Framework Mecanismos para el manejo y reporte de errores Soporte para la internacionalización (i18n) a través de ficheros de recursos y Java Locales Soporte para fuentes de datos Y más .

cgi  Actualmente en la versión 1.tld en directorio {StrutsDirectory}/contrib/struts-el/lib a myStrutsApp/WEB-INF:     c.tld .tld struts-html-el.tld struts-bean-el.Instalando Apache Struts I   Instalar Apache Tomcat 4.2 (fichero jakarta-struts-1. E.2.tld struts-logic-el.4.apache.org/download.j: myStrutsApp Copiar ficheros .x o superior Bajar la última versión de Apache Struts de: http://struts.zip para Windows)   Crear directorio de aplicación.

.jar commons-logging.jar commmons-digester.jar commons-collections.jar jstl.jar  Lo mejor es tomar la aplicación struts-blank.jar struts-el.jar files de {StrutsDirectory}/contrib/struts-el/lib a myStrutsApp/WEB-INF/lib directory:         commons-beanutils.war como punto de partida.jar struts.jar standard.Instalando Apache Struts II  Copiar los ficheros .

 Ejemplos de uso de Struts:    .war struts-blank.2 se pueden encontrar varios ficheros .Documentación y ejemplos de Struts  En el directorio webapps de la distribución de Struts 1.war base para la creación de cualquier aplicación que use Struts etc.html se puede encontrar JavaDoc de Struts API Si se ejecuta esta aplicación web en http://localhost:8080/struts-documentation/ se puede también obtener información detallada sobre el uso de Struts struts-examples.war muy útiles:  struts-documentation.war   En el subdirectorio api/index.

Flujo de Control en Struts I .

Flujo de Control en Struts II .

action. normalmente se transfiere el control a un JSP para que visualice los resultados.  El programador deberá definir un conjunto de getters y setter y sobreescribir los métodos validate() y reset()   Los objetos Action invocados deben ser desarrollados por el programador y extienden org. extendiendo org.apache.struts.xml contiene los mappings a acciones Los form beans creados por ActionServlet deben ser implementados por el programador.ActionForm.   El fichero de configuración web. mientras que el fichero de configuración de Struts struts-config.ActionServlet es el eje de Struts.action.Flujo de control en Struts III  La clase org.0) que ejecuta la lógica de negocio La acción devuelve un objeto ActionForward al servlet que especifica el siguiente paso a ejecutar.Action.action. Dada una petición de entrada HTTP:    Crea un objeto ActionForm donde guarda y valida los parámetros de entrada Decide que objeto Action se debe invocar y le pasa el objeto ActionForm creado Transfiere control a la siguiente etapa de procesamiento de la petición (típicamente un JSP).xml contiene los url mappings para enviar las peticiones de llegada al ActionServlet. .struts. Tienen un método execute() o (perform() en Struts 1.apache.apache.struts.

xml para que envíe peticiones HTTP al ActionServet Configura el ActionServlet definiendo elementos <actionmappings> y <form-beans> en struts-config.tlds de sus etiquetas personalizadas a tu proyecto Configura tu web.war. es normalmente un buen punto de partida para desarrollar una nueva aplicación usando Struts . struts-blank.Pasos a seguir en el desarrollo de una aplicación en Struts           Diseña la aplicación en términos de las acciones.xml Define tus clases Action Define tus clases ActionForm Define clases adicionales Java representando la lógica de negocio Define tus páginas de presentación JSP Desplegar la aplicación La aplicación ejemplo suministrada con Struts. vistas y estados del modelo Añade las librerías Java de Struts y los .

struts.Actions en Struts   Se crea una acción extendiendo la clase org.action.apache.Action El ActionServlet ejecuta acciones invocando el método execute() tu clase Action  El método execute() contiene código para manipular el modelo Cabeceras y parámetros de peticiones HTTP Atributos/beans guardados en los contextos application/session/request scope Struts ActionForm asociados con la acción (opcional) El ActionMapping associado a esta acción (opcional) El objeto httpResponse  Dentro del método execute() tienes acceso a:       El método execute() devuelve un objeto ActionForward que indica al ActionServlet a dónde transferir el control a continuación .

action.xml Cada vez que se llama a la acción .apache.struts. Los parámetros son mapeados a propiedades del bean.Form Beans  Un ActionForm es un JavaBean con propiedades que corresponden a los controles de un formulario HTML.apache.struts.   Proveen un mecanismo de buffer/validate/convert que necesitamos para asegurarnos que el usuario introduce los datos esperados Actúa como puente entre el navegador y el objeto de negocio      El programador define un form bean extendiendo la clase org.DynaActionForm) Hay que definir cada una de las propiedades en la clase y escribir los getters/setters correspondientes.ActionForm (o de forma declarativa usando org.action. siguiendo las reglas de JavaBeans 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 configuración de Struts struts-config. el ActionServlet poblará las propiedades con los valores de los parámetros recibidos en el formulario HTML Las propiedades no sólo pueden ser escalares sino que también pueden ser colecciones de valores .

el método validate será invocado  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 realizó el POST en primer lugar.xml una referencia a la vista que entregó el formulario  Los form beans pueden ser usados por múltiples acciones o incluso una aplicación completa  Si se configura al ActionController para que guarde un form bean en el contexto de sesión se permitirá el uso del form bean en todas las peticiones web que llegan a la aplicación . en vez de usar un form bean como intermediario? Razones:  Los Form beans pueden ser validados antes de que una acción sea invocada  Si la propiedad validate de un elemento Action en el fichero struts-config.¿Por qué se necesitan Forms Beans?   ¿Por qué no simplemente se accede a los parámetros de una petición. junto con un mensaje de error  Es importante asignar a la propiedad input del elemento action en struts-config.xml contiene el valor true (por defecto).

String´/> <form-property name=³lastName´ type=³java.lang.lang.String´/> <form-property name=³age´ type=³java.apache.DynaActionForm <form-bean name=³checkoutForm´ type=³org.action.lang.apache.xml Una o varias propiedades dinámicas pueden ser pasadas a una instancia de org.struts.struts.action.Dynamic Action Forms   Son ActionForms creados de manera declarativa en strutsconfig.DynaActionForm´> <form-property name=³firstName´ type=³java.Integer´ initial=³18´/> </form-bean> .

passphrase.add("passphrase".heading"/> Se recomienda que el manejo de errores se lleve a cabo dentro del método execute() y el control se transfiera a la vista apropiada errors.properties) Struts proporciona etiquetas personalizadas JSP tags para acceder a estos recursos <bean:message key="prompt.  Manejo de errores    Struts proporciona un mecanismo separado para permitir la implementación de un manejador global de excepciones Struts proporciona etiquetas JSP que ayudan en la visualización de los errores en tu JSP: <html:errors property=³passphrase´/> .new ActionError("error.Recursos de String/Manejo de Errores  Recursos de String   Todos los strings usados en mensajes en JSPs tanto de datos de aplicación como de errores puedes ser colocados en un ficheros de recursos (ApplicationResources.goodguess.required")).

 Ejemplo:    ApplicationResources_eu.properties Otros ficheros de recursos adicionales pueden ser definidos que incluyen el idioma a usar en el nombre del fichero. y luego ser usados en tus JSPs Los strings del idioma por defecto se guardan en el fichero ApplicationResources.properties (Contiene mensajes en Euskera) ApplicationResources_es. sus librerías de etiquetas personalizadas y Java Locales Se pueden definir strings a visualizar en tu fichero de recursos. por ejemplo. debajo del directorio WEBINF/classes .properties (Contiene mensajes en Castellano) Para cambiar el idioma preferido en IE: Tools Internet Options Languages   Los navegadores envían la cabecera HTTP Accept-Language en cada petición que indica cuál es el idioma preferido por el usuario Los ficheros de recursos deben colocarse en un lugar accesible desde el CLASSPATH de la aplicación web.Internationalization i18n     Struts soporta internacionalización a través de ficheros de recursos.

apache.Action Servlet Configuration --> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.ActionServlet</servlet-class> <init-param> <param-name>application</param-name> <param-value> com.do</url-pattern> </servlet-mapping> </web-app> .xml de aplicación usando Struts <web-app> <!-.ApplicationResources </param-value> </init-param> <init-param> <!± etc.Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.ejsp.resources.struts.action. --> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-.struts.develop.Ejemplo web.

xml Leído por la framework cuando arranca Fuentes de datos (data-sources) Form beans. Son poblados por el controlador con los datos del formulario Llevan a cabo validación de datos Son procesados por objetos Action   Global forwards y ActionMappings  Mapean el nombre de una acción a un objeto Action .      Contiene:   Ejecutan una petición basado en una entrega de un formulario. variaciones de JavaBeans.Configurando Struts  Como en toda framework se minimiza el código Java a escribir y se maximiza la configuración a través de ficheros XML   Struts se configura a través struts-config.

=== Global Forward Definitions === --> <global-forwards> <forward name="signin" path="/signin.develop.Ejemplo struts-config..SQLServerDriver"/> <set-property property= "maxCount" value="4"/> <set-property property= "minCount" value="2"/> <set-property property="password" value=""/> <set-property property= "url"value="someurl"/> <set-property property= "user" value="someuser"/> </data-source> </data-sources> <!-.struts.xml I <struts-config> <data-sources> <data-source name=³usuarios´> <set-property property= "autoCommit" value="false"/> <set-property property= "description" value="MessageBoard"/> <set-property property= "driverClass" value=".SigninForm"/> </form-beans> <!-.ejsp.jsp"/> </global-forwards> .beans.=== Form Bean Definitions === --> <form-beans> <form-bean name="SigninForm" type= "com.

GotoMessageAction"> <forward name="succeeded" path="/newmessage.SigninAction³ name="SigninForm" scope="session³ input="/signin.Process a user logon --> <action path="/SigninAction³ type= "com.jsp"> <forward name="succeeded" path="/groups.actions.struts.struts.jsp"/> </action> </action-mappings> </struts-config> .develop.Ejemplo struts-config.ejsp.develop.ejsp.jsp"/> </action> <action path="/GotoReplyToAction³ type= "com.=== Action Mapping Definitions === --> <action-mappings> <!-.jsp"/> <forward name="failed" path="/groups.jsp"/> <forward name="failed" path="/groups.xml II <!-.actions.

develop.do    El ActionServlet de Struts quita la extensión (.do) y mira la acción correspondiente en el fichero de configuración Struts para la acción GotoReplyToAction Si la encuentra encontrará o creará una instancia del tipo (type) indicado: com.actions.GotoMes sageAction El método execute() será invocado en el objeto GotoMessageAction:  Este es el lugar donde la lógica de negocio de la petición es ejecutada .struts.ejsp.Procesamiento de una petición en Struts I  Si el cliente envía la petición:  http://server/app/GotoReplyToAction.

Procesamiento de petición en Struts II public class GotoMessageAction extends org. HttpServletResponse response) throws IOException. } } . ActionForm actionForm.findForward("succeeded"). return af. HttpServletRequest request.action. ServletException { // lots of code omitted for clarity.apache.Action { public ActionForward execute( ActionMapping mapping. but here the // business logic should be implemented ActionForward af = mapping.struts.

Procesamiento de petición en Struts III    De los cuatro parámetros recibidos en execute(). ActionMapping y ActionForm son específicos a Struts El objeto ActionMapping contiene información de configuración proveniente de struts-config.xml file. El objeto ActionForm contiene el bean del formulario que fue inicializado por el ActionServlet al procesar la petición .

findForward() es llamado.   El método findForward() devuelve un objeto ActionForward que es pasado al ActionServlet El objeto ActionForward contiene detalles de a dónde debería el ActionServlet enviar la petición (contiene el path del JSP que va a visualizar los resultados) .Procesamiento de petición en Struts IV  En el mapeo de la acción GotoReplyToAction hay dos posibles forward definidos:   Uno con el nombre "succeeded" y otro "failed³  Si el método execute() se completa sin errores el método ActionMapping. pasando el nombre del siguiente recurso a llamar.

findForward(³failed"))).GLOBAL_ERROR. return (new ActionForward (mapping.  Este objeto ActionErrors es ahora disponible a cualquier página o acción consecutiva.  Luego devuelve una instancia de ActionForward que redirige a "failed".  El ActionServlet guardará en el objeto request el objeto ActionErrors bajo un nombre bien conocido por Struts: request. ActionErrors errors = new ActionErrors().add (ActionErrors.errors).connect")).  La página JSP failed anterior debería tener un área donde se mostrasen los errores producidos. new ActionError("error. saveErrors(request.Manejo de errores en Struts I Struts define la clase ActionErrors que mantiene una colección de objetos ActionError.  El código añade un sólo objeto ActionError a la colección.ERROR_KEY. errors).  El string usado para construir un objeto ActionError no es un mensaje de error sino que un identificador de un recurso (i18n Struts)  .signing. pero si se llevase a cabo validación de los campos de un formulario varios errores podrían ser mostrados.setAttribute( Action. errors.

setAttribute(Message. } } . } if (!errors.MESSAGE_NAME.GLOBAL_ERROR.Manejo de errores en Struts II public class GotoMessageAction extends org.apache. return af.findForward("failed").empty()) { saveErrors(request. ActionForm actionForm. HttpServletRequest request. ActionForward af = mapping. HttpServletResponse response) throws IOException. errors). return af. ServletException { ActionErrors errors = new ActionErrors(). ActionForward af = mapping. new ActionError("error. try { // business logic omitted for clarity } catch(SQLException e) { errors.action.findForward("succeeded").add(ActionErrors. } request.struts.Action { public ActionForward execute(ActionMapping mapping. message).sqlerror")).

actions. también definido en el fichero de configuración: <form-beans> <form-bean name="SigninForm" type="com.jsp"/> <forward name="failed" path="/groups.develop.jsp"> <forward name="succeeded" path="/groups.struts.ejsp.Manejo de Formularios I   La otra acción definida en el fichero de configuración de Struts era: <action path="/SigninAction" type="com.SigninAction" name="SigninForm" scope="session" input="/signin. beans.develop.struts.jsp"/> </action> Esta acción está asociada con el formulario llamado SigningForm.SigninForm"/> </form-beans> .ejsp.

action. el ActionServlet crea un form bean Todo form bean hereda de org. que es un JavaBean serializable.ActionFor m.Manejo de Formularios II    Si una acción tiene un formulario asociado a ella (atributo name en action mapping).struts. Dos métodos en ActionForm pueden ser sobreescritos:   validate() y reset() .apache.

length() < 1)) errors.add ("username". el form bean es validado:   Si el objeto ActionErrors devuelto es null o vacío significa que la validación tuvo éxito y una instancia del form bean creado. }  El FormBean es poblado por el ActionServlet con los parámetros de la petición de entrada llamando a los métodos setXXX() correspondientes. return errors.xml . HttpServletRequest request) { ActionErrors errors = new ActionErrors().  Una vez poblado.username.required")). if ((password == null) || (password. es pasado al objeto SigningAction Si la validación falla. if ((username == null) || (username.Manejo de Formularios III public ActionErrors validate(ActionMapping mapping. en este caso SigningForm. new ActionError("error. new ActionError("error.required")).length() < 1)) errors. la petición será re-direccionada por Struts a la página que contenía el formulario inicialmente el formulario. dada por el atributo input del elemento action en struts-config.password.add("password".

password = password.. } public void setPassword(String password) { this. } . } public String getPassword() { return this. String password = null.userName = userName. .userName.. public SigninForm() {} public void setUsername(String userName) { this. } public String getUserName() { return this.password.Manejo de Formularios IV public class SigninForm extends ActionForm { String userName = null.

new ActionError("error. } public void reset(ActionMapping actionMapping. if ((userName == null) || (userName.add("password". HttpServletRequest httpServletRequest) { username = "".username. return errors.add("username".length() < 1)) errors.required")). password="".Manejo de Formularios V // accessors and mutator omitted for clarity public ActionErrors validate(ActionMapping actionMapping.length() < 1)) errors. new ActionError("error. HttpServletRequest httpServletRequest) { ActionErrors errors = new ActionErrors().required")). } } .password. if ((password == null) || (password.

} } } . // etc.struts.apache. ActionForm form. String password = ((SigninForm) form). HttpServletRequest request. HttpServletResponse response) throws IOException.Manejo de Formularios VI public class SigninAction extends org. ServletException { try { String username = ((SigninForm) form). getPassword(). getUserName().action.Action { public ActionForward execute(ActionMapping mapping.

request. request.MESSAGE_ID)). message.getParameter( Message. la habilidad de configurar y usar referencias a javax.DataSources en Struts try { DataSource ds = servlet.DataSources El extracto de struts-config. Struts provee las clases GenericDataSource y GenericConnection que son wrappers sobre los objetos JDBC Connections y DataSources definidos en el fichero de configuración.jdbc. . message = new Message().findDataSource(³usuarios´).getMessage(ds.getParameter( GROUP_ID_NAME)) }    El código arriba muestra otra característica de Struts.xml anteriormente mostrado tiene una sección <data-sources> para configurar las data sources de la aplicación.

com/lpt/a/4034 La framework Struts proporciona un conjunto de 6 librerías de etiquetas.onjava. que asisten en la tarea de la creación de la vista de MVC para evitar incluir código Java en los JSPs:       Bean Tags HTML Tags Logic Tags Nested Tags Template Tags Tiles Tags  Las funcionalidad de las etiquetas definidas en las librerías Bean y Logic es también provista por las librerías core y fmt de JSTL  Se recomienda el uso de las librerías en JSTL .Struts Tag Libraries   Documentadas en http://www.

HTML Tags  Estas etiquetas son principalmente usadas para:   Crear formularios de entrada de datos y Otras utilidades para visualizar interfaces basados en HTML.  Algunas de las acciones más útiles son:        . base genera un elemento HTML <base> errors condicionalmente visualiza un conjunto acumulado de mensajes de error form define un formulario de entrada text visualiza un campo de entrada de tipo texto messages condicionalmente visualiza un conjunto de mensajes acumulados submit visualiza un botón de entrega Etc.

Etc.Logic Tags  Usadas para:    Iterar sobre colecciones Generación condicional de salida.  Algunas de las acciones más útiles son:      . y Flujo de aplicación present genera el contenido de marcado dentro de esta etiqueta si el valor indicado es encontrado en esta petición notPresent lo opuesto a present iterate repite el contenido anidado dentro de esta etiqueta al iterar sobre una colección forward transfiere control a la página especificada por la entrada ActionForward.

Tiles Tags (Framework)   La librería de etiquetas Tiles es un super-conjunto de la librería Templates Intenta evitar la duplicación de contenido de lenguaje de marcado dentro de una aplicación web con respecto al lookand-feel de un portal:  Un mecanismo normalmente utilizado es usar la directiva jsp:include para añadir cabeceras/menús y pies de páginas a un portal web  Tiles reduce el tamaño de código redundante en una aplicación web y separa el contenido de la visualización del mismo de manera más eficiente  Tiles define Layout Managers para JSPs  Su objetivo principal es evitar en los JSPs contenido de marcado que corresponda con el layout del portal factoriza este marcado. de tal manera que la modificación del layout sea sencilla y eficiente .

JSP Templates  Un template es una página JSP que usa una librería de etiquetas personalizadas para describir la disposición (layout) de los componentes de la página   Define cómo aparecerán las páginas JSP de una aplicación. sin especificar el contenido Esta definición es utilizada por todos los JSPs sin necesidad de mezclar layout con contenido .

js"></script> <link rel="stylesheet" href="stylesheets/format_win_nav_main.css" type="text/css"> </head> <body topmargin="0" leftmargin="0" bgcolor="#FFFFFF"> <!-.tld" prefix="logic" %> <%@ taglib uri="/WEB-INF/struts-bean.Ejemplo Tiles: index.jsp I <%@ taglib uri="/WEB-INF/struts-html.title"/></title> <html:base/> <script language=javascript src="include/scripts.inc"%> .tld" prefix="bean" %> <html:html> <head> <title><bean:message key="global.Header Page Information --> <%@ include file="include/head.inc"%> <!-.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.Nav Bar --> <%@ include file="include/menubar.

gif" width="90" border="0"/></td> </tr> <tr> <td><html:img height="1" alt="" page="/images/spacer.gif" altKey="label.inc"%> </body> </html:html> .inc"%> <%@ include file="include/copyright.featuredproducts"/></td> <td width="1" bgcolor="#9E9EFF"><html:img height="1" alt="" page="/images/spacer.gif" width="1" border="0"/></td> <td width="1" bgcolor="#9E9EFF"><html:img height="1" alt="" page="/images/spacer.THIS WEEK'S FEATURES --> <%@ include file="include/featureditems.gif" width="21" border="0"/></td> <td colspan="4" bgcolor="#9E9EFF"><html:img height="1" alt="" page="/images/spacer.Ejemplo Tiles: index.inc"%> <!-.Featured Items Header Row --> <table width="645" cellpadding="0" cellspacing="0" border="0"> <tr> <td width="21"><html:img height="1" alt="" page="/images/spacer.gif" width="1" border="0"/></td> <td width="90" bgcolor="#9E9EFF" align="right"><html:img height="1" alt="" page="/images/spacer.jsp II <%@ include file="include/mainoffer.gif" width="1" border="0"/></td> </tr> </table> <html:img height="10" alt="" page="/images/spacer.gif" width="1" border="0"/><br> <!-.gif" width="1" border="0"/></td> <td width="534"><html:img page="/images/week_picks.

Ejemplo Tiles: storefront DefaultLayout.tld´ prefix=³bean´ %> <%@ taglib uri=³/WEB-INF/tiles.tld´ prefix=³tiles´ %> <html:html> <head> <title><bean:message key=³global.tld´ prefix=³html´ %> <%@ taglib uri=³/WEB-INF/struts-bean.title´/></title> <html:base/> </head> <body topmargin=³0´ leftmargin=³0´ bgcolor=³#FFFFFF´> <tiles:insert attribute=³header´/> <tiles:insert attribute=³menubar´/> <tiles:insert attribute=³body-content´/> <tiles:insert attribute=³copyright´/> </body> </html:html> .jsp <%@ taglib uri=³/WEB-INF/struts-html.

tld´ prefix=³tiles´ %> <tiles:definition id=³storefront.default´ page=³/layouts/storefrontDefaultLayout.jsp <%@ taglib uri=³/WEB-INF/tiles.jsp´/> <tiles:put name=³menubar´ value=³/common/menubar.Ejemplo Tiles: storefrontdefs.jsp´ scope=³request´> <tiles:put name=³header´ value=³/common/header.jsp´/> </tiles:definition> .jsp´/> <tiles:put name=³copyright´ value=³/common/copyright.

jsp´ %> <tiles:insert beanName=³storefront.struts.tld´ prefix=³tiles´ %> <%@ include file=³.tiles.fr/~dumoulin/tiles/index..jsp <%@ taglib uri=³/WEB-INF/tiles.html Para instalar Tiles en Struts es necesario añadir una sección plug-in en struts-config.default´ beanScope=³request´> <tiles:put name=³body-content´ value=³index-body.apache.jsp´/> </tile:insert>   Para más información sobre Tiles Framework ir a: http://www./common/storefront-defs.Ejemplo Tiles: index.xml para la clase: org.TilesPlugin .lifl.

Mi primera aplicación con Apache Struts  Aplicación para llevar a cabo login   Una vez que el usuario ha hecho login las páginas cambian para indicar tal circunstancia Consiste de dos pantallas:   Página Welcome que saluda al usario y ofrece enlaces a la aplicación Página Logon que permite al usuario introducir username y password  Esta página lleva a cabo la validación que los datos introducidos son correctos .

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

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

jsp II <html:base/> garantiza que referencias a imágenes o otros recursos son relativas a la localización del JSP <logic:present name="user"> <H3>Welcome <bean:write name="user" property="username"/>!</H3> </logic:present>  Esta etiqueta personalizada asegura que el usuario solamente es saludado si ha efectuado login  <logic:notPresent> tiene el comportamiento opuesto <LI><html:link forward="logon">Sign in</html:link></LI>  Struts reescribe automáticamente los enlaces para mantener la sesión del usuario.Welcome.  . También permite dar a los enlaces un nombre lógico y luego guardar los enlaces reales en un fichero de configuración.

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

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

Logon.jsp II
<%@ taglib uri="/tags/struts-html" prefix="html"%>  La librería de etiquetas html definida por Struts es disponible a la página  <html:errors/> garantiza si ha habido algún error durante el login, que estos errores sean visualizados <html:form action="/LogonSubmit" focus="username">  Produce un formulario HTML para la entrada de datos. También genera JavaScript para mover el cursor al campo username del formulario 

La propiedad action hace referencia a un componente ActionMapping en el fichero de configuración de Struts dice al formulario que JavaBean (derivado de ActionForm) debe usar para poblar los controles de HTML.

jsp III <html:text property="username"/>  Crea un control de entrada HTML para un campo de texto.Logon. Asignará a este campo la propiedad username del JavaBean de ayuda antes mencionado. Dos objetos serán invocados cuando se usen estos botones:   ActionForm Action .  <html:password> crea un campo de entrada  <html:submit> y <html:reset> generan botones HTML Submit y Reset.

Configuración de la acción logon I  Configuración para la pantalla de logon:   JSP hace referencia al /LogonSubmit ActionMapping ActionMapping hace referencia a los objetos:   app.LogonAction lleva a cabo el procesamiento del formulario .LogonForm describe propiedades usadas por el formulario logon app.

jsp"/>  path identicador único para el mapping  type acción a invocar cuando el formulario es entregado  name el helper JavaBean (ActionForm) a usarse con el formulario HTML  scope indica en qué contexto debe guardarse el ActionForm  validate indica si es necesario invocar al método validate del ActionForm antes de invocar al objeto Action  input indica a donde ir si validate devuelve falso <form-bean name="logonForm" type="app.Configuración de la acción logon II <html:form action="/LogonSubmit" focus="username">  La configuración asociada al atributo acción en Struts sería: <action path="/LogonSubmit" type="app.LogonForm .LogonForm"/>  Este extracto del fichero de configuración relaciona el nombre lógico logonForm con la clase app.LogonAction" name="logonForm" scope="request" validate="true" input="/pages/Logon.

bajo una clave conocida por la etiqueta html:errors  Los tokens error.add ("username". }  Si validate no devuelve null.add("password".username.password.length() < 1)) errors.required")). new ActionError("error. return errors. .username. if ((password == null) || (password. entonces el ActionController servlet guardará el objeto ActionErrors devuelto en el contexto request.length() < 1)) errors. if ((username == null) || (username. new ActionError("error. HttpServletRequest request) { ActionErrors errors = new ActionErrors().required y error.password.required son claves que son utilizadas para mirar los strings correspondientes en el fichero de recursos de Struts  Recordar que cada Locale contiene su propio fichero de recursos lo que hace que los mensajes sean fácilmente localizables.required")).LogonForm: un ejemplo de un ActionForm public ActionErrors validate(ActionMapping mapping.

import org.servlet.HttpServletResponse.ActionErrors.HttpSession.struts. import org.struts.ActionMapping.action.struts. import org.servlet. import javax. public final class LogonAction extends Action { // Validate credentials with business tier public boolean isUserLogon (String username.action. } // end isUserLogon .action.apache. import java.password)).LogonAction: un ejemplo de un LogonAction I package app. import org.ActionForm. import org.servlet.apache.apache.isValidPassword(username.IOException.apache.struts.action.http.action.struts.servlet. import javax.HttpServletRequest.ActionError.http.struts.apache. String password) throws UserDirectoryException { return (UserDirectory. import javax.action.action. import org.struts.Action.ActionServlet.http.apache.ActionForward.apache.getInstance().io. import org.ServletException. import javax.

if appropriate if (servlet. ActionForm form.getUsername().append("' logged on in session "). } // Return success return (mapping. new ActionError("error. ServletException { // Obtain username and password from web tier String username = ((LogonForm) form). errors.logon. } // Save our logged-in user in the session.findForward (Constants. form).GLOBAL_ERROR.add (ActionErrors.toString).log(message.USER_KEY. saveErrors(request.setAttribute(Constants. } catch (UserDirectoryException ude) { // couldn't connect to user directory ActionErrors errors = new ActionErrors(). HttpSession session = request. HttpServletResponse response) throws IOException.append(session. HttpServletRequest request.getId()).password).LogonAction: un ejemplo de un LogonAction II public ActionForward execute(ActionMapping mapping. // Log this event. message.getDebug() >= Constants. because we use it again later. // return to input page return (new ActionForward (mapping. servlet. message. } // end perform } // end LogonAction .WELCOME)).DEBUG) { StringBuffer message = new StringBuffer("LogonAction: User '"). message. try { validated = isUserLogon(username.errors).connect")).getSession().append(username).getPassword(). // Validate credentials boolean validated = false. String password = ((LogonForm) form). session.getInput())).

} catch (UserDirectoryException ude) { // couldn't connect to user directory ActionErrors errors = new ActionErrors(). En este caso se envía control al forward success declarado en el fichero de configuración como: <forward name=³success´ path=³/pages/Welcome.findForward (Constants. new ActionError("error.LogonAction: un ejemplo de un LogonAction III // Validate credentials boolean validated = false.  Un objeto de tipo ActionForward será devuelto al ActionServlet si todo va bien.errors). Lo mismo se lleva a cabo si se puede contactar al servicio de directorio pero el login del usuario no es correcto return (mapping. errors.jsp´/> .password).logon.add (ActionErrors. }  Si un error es encontrado mientras se lleva a cabo la validación de la entrada del usuario y una excepción es lanzada.WELCOME)).connect")). entonces el error es transformado en un ActionError y el control es devuelto a la página de entrada. // return to input page return (new ActionForward(mapping.getInput())).GLOBAL_ERROR. saveErrors(request. try { validated = isUserLogon(username.

Modificar action /guess en struts-config. 6. 3.deusto. . haciendo que esa acción esté asociada a la clase es.guessing. 2. el usuario podrá realizar intentos infinitamente.xml.Modificaciones a realizar en guessing 1.form. pero esos intentos hay que contabilizarlos y visualizarlos cada vez que el usuario falla o adivina el número 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 un usuario Idealmente crear una clase llamada Game que contenga el número a adivinar y el número de intentos fallidos Modificar la aplicación de manera que nuevos usuarios puedan ser definidos y los datos de login de esos usuarios se salven en un fichero .GuessingForm.guessing.jsp y GuessingForm Asegurarse que un usuario después de haber hecho login pueda jugar una partida.deusto. 4.properties. Asegurarse que existe correspondencia entre clase guessing.action.GuessingAction y al formulario es. 5.

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

Sign up to vote on this title
UsefulNot useful