Introducción a Struts Prerequisitos Esta guía de usuario está escrita para desarrolladores Web activos, y asume que tenemos

conocimientos sobre como funcionan las aplicaciones Web Java. Antes de empezar, deberíamos entender los básico de estas tecnologías:     La secuencia Solicitud/Respuesta HTTP. La fuente canónica para esto es RFC 2616 - Hypertext Transfer Protocol (HTTP/1.1). Java Servlets. Un buen lugar para empezar es Sun Servlet product page y Sun Java Tutorials. JavaServer Pages (JSP). De igual forma, un buen lugar para emepzar es la Sun JSP product page y Sun Java Tutorials. JavaBeans. Muchas clases Struts están escritas como JavaBeans. Si no has trabajado antes con JavaBeans, puedes ver la página Sun JavaBean product page y Sun Java Tutorials.

Si hemos creamos aplicaciones Web sobre otras plataformas, probablemente podremos seguir, y luego visitar las referencias arriba indicadas cuando lo necesitemos. Estas son tecnologías corazón que se utilizan en casi todos los proyectos desarrollados en Java Prefacio: Un paso hacia el pasado (o una breve historia de Struts) Cuando se inventaron los Servlets Java, muchos programadores se dieron cuenta de que eran una Buena Cosa. Eran más rápidos y más potentes que el CGI estándard, portables, y extensibles infinitamente. Pero escribir infinitas sentencias println() para enviar HTML al navegador era tirano y problemático. La respuesta fueron las JavaServer Pages, que nos dejaron escribir servlets dentro de ellas. Ahora los desarrolladores podían mezclar fácilmente HTML con código Java, y tener todas las ventajas de los servlets. ¡El cielo era el límite! Las aplicaciones web Java se convirtieron rápidamente en "centradas-en-JSP". Esto, por sí sólo no era en una mala cosa, pero hacían poco por resolver problemas de control de flujo y otros problemas endémicos de las aplicaciones Web. Claramente se necesitaba otro modelo... Muchos desarrolladores inteligentes se dieron cuenta que las JavaServer Pages Y y los servlets se podrían usar juntos para desplegar aplicaciones web. Los servlets podrían ayudar con el control de flujo, y las JPSs podrían enfocarse en el negocio odioso de escribir HTML. Usar JSP y servlets juntos se ha dado ha conocer como el Modelo 2 (cuando usar sólo JSPs era el Modelo 1). Por supuesto, no hay nada nuevo bajo el Sol (Sun)... y muchos han apuntado rápidamente que el Modelo 2 de JSPs sigue el clásico patrón de diseño Modelo-Vista-Controlador de SmallTalk. Ahora es muy común usar los terminos Modelo 2 y MVC indistintamente. El proyecto Struts lo lanzó en Mayo del 2000, Craig R. McClanahan para proporcionar un marco de trabajo MVC estándard a la comunidad Java. En Julio del 2001, se liberó Struts 1.0, e IOHO, el modelo 2 de desarrollo Java nunca será lo mismo. El Patrón de Diseño ('MVC') Modelo-Vista-Controlador En el patrón de diseño MVC, el flujo de la aplicación está dirigido por un Controlador central. El Controlador delega solicitudes en nuestro caso, solicitudes HTTP -- a un manejador apropiado. Los manejadores están unidos a un Modelo, y cada manejador actúa como un adaptador entre la solicitud y el Modelo. El Modelo representa, o encapsula, un estado o lógica de negocio de la aplicación. Luego el control normalmente es devuelto a través del Controlador hacia la Vista apropiada. El reenvío puede determinarse consultando los conjuntos de mapeos, normalmente cargados desde una base de datos o un fichero de configuración. Esto proporciona un acoplamiento cercano entre la Vista y el Modelo, que puede hacer las aplicaciones significativamente más fáciles de crear y de mantener. Introducción al Marco de Trabajo de Struts Creyendo en el patrón de diseño Modelo-Vista-Controlador, las aplicaciones Struts tiene tres componentes principales: un servlet controlador, que está proporcionado por el propio Struts, páginas JSP (la "vista"), y la lógica de negocio de la aplicación (o el "modelo"). Veamos como esto funciona todo junto. El servlet controlador Struts une y enruta solicitudes HTTP a otros objetos del marco de trabajo, incluyendo JavaServer Pages y subclases org.apache.struts.action.Action porporcionadas por el desarrollador Struts. Una vez inizializado, el controlador analiza un fichero de configuración de recursos, La configuración de recursos define (entre otras cosas) los org.apache.struts.action.ActionMapping para una aplicación. El controlador usa estos mapeos para convertir las solicitudes HTTP en acciones de aplicación. Un ActionMapping normalmente especificará:  una path solicitado (o "URI"),

para que la Action pueda enfocarse en el manejo de errores y dónde reenviar el control. subclasificando org. o indicar a que control debería ser reenviado. Este objeto entonces puede chequear los contenidos del bean de formulario antes de que su formulario de entrada se muestre. El bean se graba en una de las colecciones estándard o de contexto compartidas. Esto encapsula la lógica del negocio. Los JavaBeans también se pueden usar para manejar formularios de entrada. por un objeto Action para validar los datos introducidos por el usuario . y otras propiedades según se necesite. El bean de formulario puede usarlo una JSP para recoger datos del usuario . debería llamar a otro objeto. en una aplicación de base de datos:     Un bean de lógica de negocio conectaría y consultaría la base de datos. incluyendo JavaBeans. Ni el objeto Action ni la página JSP necesitan saber (o no les importa) de dónde viene le resultado. o un ítem de la tarjeta. Cuando una solicitud llama a un Action que usa un bean de formulario. Sólo necesitan saber cómo empaquetarlo y mostrarlo.struts. en lamayoría de los casos. y también la cola de mensajes a manejar por el formulario. el servlet controlador recupera o crea el bean formulario. el objeto Action puede devolver el control con un reenvio a su formulario de entrada. especialmente un objeto Action. Struts tiene un mecanismo compartido para lanzar y mostrar mensajes de error. y luego de nuevo por la JSP para rellenar los campos del fomulario. simplemente añadimos otro fichero de recurso. El controlador puede responder a la solicitud HTTP y dirigir al cliente a la JavaServer Page. y la posibilidad de revisar todas las etiquetas y mensajes desde una localización central. un objeto Action puede reenviar indirectametne uno o más objetos compartidos. Las etiquetas personalizadas en el marco de trabajo Struts están diseñadas para usar las características de internacionaización incluidas en la plataforma Java. La JavaServer Page mostraría el resultado en un formulario HTML. Lo único que la mayoría de las páginas JSP necesitan saber sobre el resto del marco de trabajo son los nombres de los campos apropiados y dónde enviar el formulario. Los objetos Action tienen acceso al servlet controlador de la aplicación.. y Java puede proporcionar automáticamente el recurso correcto para el idioma y país de un cliente. para realizar la lógica de negocio real. Este mapeo podría usar una página JavaServer Page para mostrar los contenidos de la tarjeta del usuario. Cuando esta listo. Cuando se reenvia un control. En el caso de validación de errores. por eso puede ser usado por otros objetos. Por ejemplo. En una aplicación Struts. usando un JSP. si un logín tiene éxito. Una Action puede llamar a las propiedades de un JavaBean sin conocer realmente como funciona. Para proporcionar mensajes para otro idioma.apache. Como cada cliente tiene su propia sesión. Esto permite al objeto Action enfocarse en el manejo de errores y el control de flujo. la mayoría de la lógica del negocio se puede representar usando JavaBeans. El objeto Action almacenarçia el resultado en un bean formulario en la solicitud. Todas las etiquetas de campos y los mensajes pueden recuperarse desde un recurso de mensajes.ActionForm. un objeto Action. y por eso tienen acceso a los métodos del servlet. También se pueden definir otras etiquetas especificas de la aplicación para ocultar detalles de implementación de las páginas JSPs. normalmente un JavaBean.action. Los componentes como los mensajes "encolados" por el Action pueden salir usando una simple etiqueta personalizada. un objeto Action podría algunas veces manejar la lógica de negocio asociada con una solicitud. situándolos en una de las colecciones estándard compartidas por los servlets Java. Un problema clave en el diseño de aplicaciones Web es retener y validar lo que el usuario ha introducido entre solicitudes.. otros beneficios de esta aproximación son las etiquetas consistentes entre formularios.. y almacenar fácilmente los datos de un formulario de entrada en estos beans formularios. cada uno también tendrá su propia tarjeta de compra. podemos definir un conjunto de clases bean formulario. El objeto Action debería traducir los detalles necesarios de la solicitud HTTP y pasarlos a los beans de la lógica del negocio como variables normales de Java. El objeto Action puede manejar la solicitud y responder al cliente (normalmente un navegador Web). Para la aplicación más simple. .  El tipo objeto (subclase de Action) para actuar sobre la solicitud. El bean de lógica de negocio devolvería el resultado al objeto Action. en vez de en la lógica del negocio.. El marco de trabajo Struts incluye etiquetas personalizadas que pueden rellenar automáticamente los campos de un formulario o un bean de formulario. Junto al internacionalismo. Un bean de formulario Struts se declara en la configuración de recursos definida en un fichero fuente Java. Sin embargo. Con Struts. y luego reenviando el control a otro mapeo. Para permitir su reutilizacion en otras plataformas. Por ejemplo. y enlazado a un ActionMapping usando un nombre de propiedad comnún. una acción logín podría desear reenviar la petición hacia el mainMenu. los JavaBeans de lógica de negocio no deberían referirse a ningún objeto de aplicación Web. Un objeto acción puede crear un bean de tarjeta de compra. y lo pasa el objeto Action. situando el bean en la colección de sesión.

y normalmente especifica el nombre totalmente cualificado de clase de una clase Action. Estas características nos ayudan a separar la lógica de control (qué hacer) de la lógica de la vista (cómo se renderiza). sin saber el nombre real de la página JSP correspondiente. El uso de estas etiquetas se explica más adelante en detalle. Este bean también podría tener un método checkOut() que autorice la tarjeta de crédito del usuario. Todas las Actions son subclases de org. interpretan la salida. normalmente los objetos de negocio necesitan poder dibujarse a sí mismos en HTML (o XML). Por ejemplo. En Struts. quizas como Session Enterprise JavaBeans (Session EJBs). Puedes ver las especificaciones en ASF license. y las acciones que pueden tomarse para cambiar el estado. Otros sistemas representarán las acciones disponibles de forma separada. Struts nos permite definir nombres lógicos para los controles a los que se debería reenviar para que un método actión pueda preguntar por la página "Main Menu" (por ejemplo). Además.action. Por otro lado. podríamos tener un bean de una tarjeta de compra. Las aplicaciones de gran escala normalmente representarán un conjunto de posibles acciones lógicas de negocio con métodos que pueden ser llamados sobre los beans que mantienen su información de estado. Generalmente. almacenado en el ámbito de sesión por cada usuario actual con las propiedades que representan el conjunto actual de ítems que el usuario ha decidio comprar. Además. Esto nos permite almacenar información adicional específica de nuestra aplciación. estos beans pueden ser autocontenidos (y saber como guardar su información de estado persistentemente de alguna forma). pero nosotros recomendamos encarecidamente separar la lógica de negocio ("cómo se hace") del rol que juegan las clases Action ("que hace"). El Controlador: ActionServlet y ActionMapping La parte Controlador de la aplicación está enfocada en las solicitudes recibidas desde el cliente (normalmente un usuario ejecutando un navegador Web). El entorno JSP incluye un conjunto de etiquetas estándard. y envíe el pedio al almacen para que sea remitido. por supuesto. o donde no está contemplada la reutilización de la lógica de negocio en otros entornos. basándose en su estado actual en el momento de la solicitud.Action. Los Entity Enterprise JavaBeans (Entity EJBs) también se usan comunmente para representar estados internos. Dependiendo de la complejidad de nuestra aplciación. y que interactúan amigablemente con beans ActionForm que son parte del Modelo del sistema. . el API estándard JavaDoc. pero aún utiliza las características restantes del marco de trabajo. las acciones disponibles podrían estar embebidas dentro de clases Action que son parte del rol del Controlador. Struts incluye una extensa librería de etiquetas personalizadas que facilitan la creación de interfaces de usuario que están completamente internacionalizados. el código fuente completo! Struts se distribuye bajo la licencia de la Apache Software Foundation. En términos gramáticos. con propiedades que representan los detalles del estado. junto con aplicaciones de ejemplo. que están organizadas en "librerías de etiquetas personalizadas". o podrían ser fachadas que saben cómo recuperar información de fuentes externas (como una base de datos) cuando es solicitado. La salida renderizada desde dichos objetos puede incluirse fácilmente en una página JSP resultante usando la etiqueta de acción estándard <jsp:include>. y. La Vista: Páginas JSP y Componentes de Presentación La parte de la Vista de una aplicación basada en Struts generalmente está construida usando tecnología JavaServer Pages (JSP). La versión Struts también incluye varias Guías de Desarrollo que cubren varios aspectos de los marcos de trabajo. Además de las páginas JSP y la acción y las etiquetas personalizadas que contienen. podríamos pensar en la información de estado como nombres (cosas) y las acciones como verbos (cambios del estado de esas cosas). Esto es apropiado cuando la lógica es muy simple. Struts también soporta la habilidad de usar clases ActionMapping que tienen propiedades adicionales más allá de las estándard requeridas para operar el marco de trabajo.struts. como <jsp:useBean>. el componente principal del Controlador es un servlet de la clase ActionServlet.El resto de esta guía de usuario explica varios componentes Struts en gran detalle. y luego delegando la responsabilidad para producir la siguiente fase del interface de usuario en un componente Vista apropiado. Este servlet está configurado definiendo un conjunto de ActionMappings. y por último despachan el control al componente Vista apropiado para la respuesta creada. decidiendo qué función de la lógica de negocio se va a realizar. Las acciones encapsulan la lógica del negocio. Las págnas JSP pueden contener texto HTML estático (o XML) llamado "plantilla de texto". El código tiene copyright pero es gratuito para usarlo en cualquier aplciación. El marco de trabajo Struts soporta cualquiera de estas aproximaciones. nuestra aplicación representará un estado interno del sistema como un conjunto de uno o más JavaBeans. Un ActionMapping define un path que se compara contra la URI solicitada de la solicitud entrante. en algunas aplicaciones de menor escala. El Modelo: Estado del Sistema y JavaBeans de la Lógica de Negocio La parte del Modelo de un sistema basado en MVC puede dividirse en conceptos--el estado interno del sistema. hay una facilidad estándard para definir nuestras propias etiquetas.apache. además de la habilidad de insertar contenido dinámico basado en la interpretación (en el momento de solicitud de la página) de etiquetas de acción especiales.

los Javabeans pueden almacenarse en (y ser accedidos desde) varias colecciones de "atributos" diferentes. La natural precisión de los beans requeridos por una aplicación particular variará mucho dependiendo de esos requerimientos. Sin embargo.MyApp. Juntos. pero generalmente pueden clasificarse en varias categorías descritas abajo. application . sin lógica de negocio.Beans que son visibles para todas las páginas JSP y los servlets que forman parte de una aplicación Web. Esto opera de una forma similar a la acción JSP estándard <jsp:setProperty> cuando usamos el comodín asterisco para seleccionar todas las propiedades. al igual que las aplicaciones Web comparten los mismos conjuntos de colecciones de beans. session . así como EN cualquier página o servlet que esté incluido en esta página. Por ejemplo.Beans que son visibles para todas las páginas JSP y los servlets que participan en una sesión de usuario particular. el desarrollador de componentes del Modelo se enfocará en la creación de clases JavaBeans que soporten todos los requerimientos de funcionalidad. Los beans ActionForm algunas veces son sólo llamados "beans formuLario". Sin embargo.mycompany. un bean ActionForm sólo tendrá metodos setxxx() y getxxx(). Por cada parámetro de la solicitud cuyo nombre corresponda con el nombre de una propiedad del bean. a través de una o más solicitudes. (Atributos Session). Si no está disponible dicho bean en el ámbio de la sesión. y la visibilidad de los Beans almacenados en ella. el servlet controlador Struts realiza automáticamente los siguientes servicios por nosotros. se crea uno nuevo automáticamente y se añade a la sesión de usuario. En general.setAttribute("cart".). o reenviado por esta página. Se usa para identificar el rol que esos beans particulares juegan en la arquitectura general.Beans que son visibles dentro de una sóla página JSP.Beans que son visibles dentro de una sóla página JSP. Cuando codifiquemos nuestros beans ActionForm. request. bajo la clave apropiada. debemos tener en mente los siguientes principios:  La propia clase ActionForm no requiere que se implemente ningún método específico. Normalmente. deberíamos asegurarnos que también está claramente definido el procesamiento requerido por cada solicitud enviada desde la perspectiva del Modelo. La especificación JavaServer Pages (JSP) define las elecciones de ámbito usando los siguientes términos (con el concepto del API Servlet equivalente entre paréntesis):     page . Los JavaBeans y el Ámbito Dentro de una aplicación basada en web. usando una etiqueta de acción estándard como esta: <jsp:useBean id="cart" scope="request" class="com.. . (Atributos Request). El bean ActionForm actualizado será pasado al método perform() de la clase Action cuando es llamado. un Bean almacenado como un atributo request en un servlet como este: MyCart mycart = new MyCart(.Construir los Componentes del Modelo Introducción Muchos documentos de requerimientos usados para construir aplicaciones Web se enfocan en la Vista. El marco de trabajo Struts generalmente asume que hemos definido un bean ActionForm (es decir. se llamará al correspondiente método set(). para el tiempo de vida de la solicitud actual (Variables locales del método service() ) request . las reglas que definen el tiempo de vida y la visiblidad se llama el ámbito de esos beans.MyCart"/> Beans ActionForm Nota: los beans ActionForm están realmente más cercanos a la Vista que al Modelo. es inmediatamente visible a una página JSP a la que se reenvíe este servlet. mycart). primero es útil una breve revisión del concepto de "ámbito" en relación con los beans y JSP. haciendo que esos valores estén disponibles inmediatamente. una clase Java que extiende la clase ActionForm) por cada formulario de entrada necesario en nuEstra aplicación. antes de llamar al método Action apropiado:     Chequea en la sesión de usuario si hay un ejemplar de un bean de la clase apropiada. (Atributos de contexto Servlet). Si declaramos dichos beans en nuestro fichero de configuración ActionMapping (ver "Construir los Componentes del Controlador").. Es importante recordar que las páginas JSP y los servlets. Cada colección tiene diferentes reglas para el tiempo de vida de esa colección.

los beans de estado del sistema representarán información que está almacenada permanentemente en alguna base de datos externa (como un objeto CustomerBean que responde a una fila de la tabla CUSTOMERS). Dependieno de la complejidad y del ámbito de nuestra aplicación. Para grandes aplicaciones. Si seguimos estas sugerencias. También podríamos situar un ejemplar bean en nuestro formulario. y usar referencias a propieades anidadas. Deberías haber observado que un "formulario". en un interface de usuario al estilo de los wizard que se utilizan comunmente cuando instalamos nuevas aplicaciones. y son creados o eliminados de la memoria del servidor cuando se necesita.     El objeto ActionForm también ofrece un mecanismo de validación estándard. Esta envoltura también puede proporcionar un filtro para asegurarnos en tiempo de ejecución de que las propiedades no se seleccionan con valores inapropiados. Por supuesto. Un ActionForm que falla en la validación incluso ni será presentado para el manejo del Action. frecuentemente sin requerir que cambiemos la lógica de procesamiento. Cualquier propiedad pública en un ActionForm que acepta un simple valor String puede seleccionarse con un string de consulta. e incluirá (entre otras cosas) un conjunto de ítems que el comprador ha seleccionado. Ver Validación del Formulario para más detalles. Es común en muchas aplicaciones tener un "formulario" (desde la perspectiva del usuario) que se extienda sobre múltiples páginas. por ejemplo. Debemos considerar reordenar las cosas para que nuestras clases Action (parte del rol del Controlador.getName() y customer. un conjunto de beans de estado del sistema podría contener todos los conocimientos que el sistema tiene sobre esos detalles particulares. De igual forma. un campo de entrada llamado username hará que se llame al método setUsername(). Dicha clase de lógica de negocio podría reutilizarse en entornos distintos al de la aplicación Web para el que fue construida en un principio. incluirá un bean que represente la tarjeta que está siendo mantenida por cada comprador individual. Si nos encontramos que tenemos que importar una clase javax. estamos ligando ésta lógica de negocio al entorno de una aplicación Web. podríamos tener un bean "customer" en nuestro Action Form. los diseñadores de páginas podrán reordenar los campos entre varias páginas.servlet. cuyas propiedades definen el estado actual. El nombre del campo y el nombre de la propiedad deben corresponder de acuerdo a las convenciones usuales de los JavaBeans. Acceder a Bases de Datos Relacionales . Por ejemplo. Podría ser muy útil situar dichos beans dentro de una fina "envoltura" que exponga sólo las propiedades requeridas.* en nuestro bean. y que contienen valores razonables. el sistema también incluirá diferentes beans para la información del perfil del usuario (incluyendo su tarjeta de crédito y su dirección de envío). o JavaBeans ordinarios que aceden a una base de datos usando llamadas JDBC. Un sistema de tarjeta de compra. Para una reutilización máxima del código. Si sobreescribimos un método "stub". O. debemos pensar en las propiedades que exponemos. en el sentido discutido aquí. Definir una propiedad (asociada con métodos getXxx() y setXxx()) para cada campo que esté presente en el formulario. En el último caso. Piensa por ejemplo. así como el catalogo de ítems disponibles y sus niveles de inventario actuales. Estos métodos pueden ser parte de las mismas clases usadas para los beans de estado del sistema. los beans de lógica de negocio podrían ser JavaBeans ordinarios que interactúan con beans de estado del sistema que son pasados como argumentos. o para información de estado que no necesita guardarse durante mucho tiempo. estos beans frecuentemente ofrecerán JavaBeans Enterprise (EJBs) con o sin estado en su lugar.name" en nuestra vista JSP. como es el caso más frecuente. no corresponde necesariamente con una sóla página JSP en el interface de usuario. Separadamente. Beans de Estado del Sistema El estado real de un sistema normalmente está representado por un conjunto de una o mas clases JavaBeans. Para sistemas de pequeña escala. Struts validará automáticamente la entrada del formualrio (usando nuestro método). Los JavaBeans Enterprise de Entidad también se usan para esto en aplicaciones de gran escala. Usamos el método validate para asegurarnos de que están presentes todas las propiedades requeridas. Beans de Lógica de Negocio Deberíamos encapsular la lógica funcional de nuestra aplicación como llamadas a métodos en JavaBeans diseñados para este propósito. normalmente necesitaremos pasarle los beans de estado del sistema para que sean manipulados por estos métodos como argumentos. y proporcionamos mensajes de error en el recurso de aplicación estándard. también podemos ignorar la validación de ActionForm y proporcionar nuestro propio objeto Action. y luego referirnos a la propiedad "customer. sin importar que página de campo se está mostrando actualmente. los beans de la lógica del negocio deberían ser diseñados e implementados para que no sepan que están siendo ejecutados en un entorno de aplicación Web. después de que se pueda hacer una llamada a un método execute(). las distintas páginas del mismo formulario deberían ser reenvidas a la misma clase Action. Struts nos aconseja definir un sólo ActionForm que contenga las propiedades de todos los campos. Esto correspondería con los métodos customer.setName(string Name) de nuestro bean customer. Debemos pensar en nuestros beans ActionForm como firewall ente HTTP y el objeto Action. Por ejemplo. o podrían estar en clases separadas dedicadas a realizar la lógica. Cuidado: si anidamos ejemplares de beans existentes en nuestro formulario. según se describe abajo) traduzcan toda la información requerida desde la solicitud HTTP que está siendo procesada en llamadas a métodos setXxx() de propiedades de nuestros beans de lógica de negocio.

sql. } catch (SQLException e) { getServlet(). Después de definir la fuente de datos.close".La clase java.process". } finally { //enclose this in a finally block to make //sure the connection is closed try { myConnection. porque estos mensajes normalmente están orientados a texto. Struts se construye sobre la plataforma Java proporcionada para construir aplicaciones internacionalizadas y localizadas. Muchas aplicaciones Struts usan otros almacenes de conexiones para un mejor rendimiento. java. Los conceptos clava para familiarizarnos con ellos son:    Locale . Sin embargo.DataSource dataSource = servlet.log("Connection. que principalmente está creada usando tecnología JavaServer Pages (JSP). y una forma de representar cantidades numéricas. como fechas.util.Locale. MessageFormat .Struts puede definir las fuentes de datos para una aplicación desde dentro de un fichero de configuración estándard. Construir los Componentes de la Vista Introducción Este capítulo se enfoca en la tarea de construir los componentes de la Vista de una aplicación.util. han hecho que los límites nacionales sean invisibles en muchos casos. Esto es muy conveniente para preparar paquetes de recursos con mensajes que son usados en una aplicación Web.log("Connection. HttpServletRequest request. los desarrolladores de aplicaciones podían tener que contar sólo con los residentes de su país.La clase java.text. especialmente con sistemas de producción de alto volumen.Connection myConnection = dataSource.Una de las implementaciones estándard de ResourceBundle que nos permite definir recursos usando la misma sintaxis "nombe=valor" usada para inicializar ficheros de propiedades. recuperado de un paquete de recursos) con argumentos especificados en tiempo de ejecución. Esto se ha traducido en la necesidad de que las aplicaciones soporten la internacionalización (frecuentemente llamada "i18n" porque 18 es el número de letras entre la "i" y la "n") y localization. También se proporciona un simple almacen de conexiones JDBC. que normalmente sólo usaban un idioma (a veces dos). HttpServletResponse response) { try { javax. ResourceBundle . } } } Observa que el almacen de conexiones Struts genérico es un componente opcional. Toda Locale representa una elección particular de país e idioma (además de variantes opcionales del idioma). así como el despliegue de dichas aplicaciones sobre Internet y otras redes accesibles.MessageFormat nos permite reemplazar porciones de un string de un mensaje (en este cado.sql.ResourceBundle proporciona la herramienta fundamental para el soporte de mensajes en varios idiomas. Mensajes Internacionalizados Hace unos pocos años. //do what you wish with myConnection } catch (SQLException sqle) { getServlet(). aquí tenemos un ejemplo de cómo establecer una conexión desde dentro del método perform de la clase Action: public ActionForward perform(ActionMapping mapping. la explosión del desarrollo de aplicaciones basadas en tecnologías Web.close(). PropertyResourceBundle .findDataSource(null). y también un conjunto de asumpciones de formateo para cosas como los números y las fechas. así como para interactúar con formularios de entrada. En particular Struts proporciona soporte para construir aplicaciones internacionalizadas.getConnection(). e). sqle).La clase fundamental Java que soporta internacionalización es java. ActionForm form. números y valores monetarios. Esto es útil  .

sin tener que re-introducir cualquier parte del resto de la información de la página o formulario actual. Otra aproximación es almacenar el fichero MyResources.. la aplicación debería permitirle corregir sólo lo que necesita ser modificado -.. El string contenedor {0} del mensaje es reemplazado por el primer argumento. Para crear un paquete de recursos llamado com.mycompany.mypackage.properties .MyResources.. En el caso descrito arriba. un elemento de entrada para un campo username podría parecerse a esto (en JSP): <input type="text" name="username" . El soporte para localidades específicas métodos de entrada (usado con idiomas como el Japonés.hello=Hola./> </servlet> Los importante para este paquete de recursos es encontrarse en el classpath de nuestra aplicación.ActionServlet</servlet-class> <init-param> <param-name>application</param-name> <param-value>com. pero las palabras podrían aparecer en diferente orden en diferentes idiomas.struts.MyResources.util. una de las cosas que necesitamos definir en un parámetro de inicialización es el nombre base del paquete de recursos para la aplicación.mycompany.La clase Struts org. el Chino y el Koreano) se deja al dispositivo del cliente. etc.mycompany. la mayoría de los desarrolladores web han construido formularios usando las capacidades estándard del HTML. <servlet> <servlet-name>action</servlet-name> <servlet-class>org.Copy any configuration files --> <copy todir="classes"> <fileset dir="src/conf"/> </copy> Interacciones de Forms y FormBean Una vez u otra.si el usuario comete un error. hay una tarea de Ant a ejecutar cuando compilemos nuestra aplicación que copia los contenidos de un directorio src/conf al directorio classes: <!-.apache. Debemos tener cuidado de no borrarlo si construimos scripts de borrado de clases como parte de una fuente de "limpieza". Más adelante. Los usuarios esperan que las aplicaciones interactivas tengan ciertos comportamientos.struts.mypackage.mycompany. Cuando configuramos el servlet controlador en el descriptor de despliegue de la aplicación Web.Contiene los mismos mensajes en el idioma cuyo código de idioma ISO es "xx".MessageResources nos permite tratar un conjunto de paquetes de recursos como una base de datos. Podemos tener ficheros de recursos para tantos idiomas como necesitemos. Conseguir esto es tedioso y aburrido cuando codificamos usando HTML y páginas JSP. sería com.mypackage.Contiene los mensajes del idioma por defecto de nuestro servidor. que normalmente es un navegador Web. {1} es reemplazado por el segundo argumento. y nos permite solicitar un string de mensajes particular para una Localidad particular (normalmente asociado con el usuario actual) en lugar de la localidad por defecto en la que el propio servidor se está ejecutando.properties . y uno de estos está relacionado con el manejo de errores -.properties en la carpeta classes de nuestra aplicación. en casos donde estámos creando una sentencia. Para una aplicación internacionalizada. observa que el soporte de i18n en un marco de trabajo como Struts está limitado a la presentación de texto e imágenes internacionalizadas al usuario. podríamos tener una entrada como esta:prompt. por eso está almacenado en un directorio (relativo a nuestro directorio fuente) llamado com/mycompany/mypackage. seguimos los pasos descritos en el documento Internationalization del paquete de documentación del JDK de nuestra plataforma para crear un fichero de propiedades que contenga los mensajes para cada idioma. tendríamos esta entrada: prompt.hello=Hello MyResources_xx. un ejemplo ilustrará esto.mypackage. Por ejemplo.action. Para una versión Española del mensaje mostrado arriba. MessageResources . como la etiqueta <input>. Entonces podremos especificar simplemente "myResources" como el valor de la aplicación.apache. Por favor. Si el idioma por defecto es Inglés. Asumimos que nuestro código fuente se ha creado en el paquete com.MyResources</param-value> </init-param> <. creariamos los siguientes ficheros en el directorio com/mycompany/mypackage:   MyResources. Si lo hace.

1.value="<%= loginBean.password"/> </th> <td align="left"> <html:password property="password" size="16"/> </td> </tr> <tr> <td align="right"> <html:submit> <bean:message key="button. y también un simple formulario multiparte. basada en la facilidad de las Librerías de Etiquetas Personalizadas de JSP 1. Construir Formularios con Struts Un ejemplo completo de un formulario de login ilustrara cómo Struts trata con los formularios de una forma menos dolorosa que usar sólo las facilidades HTML y JSP estandards. confunde a los desarrolladores HTML que no tienen conocimientos sobre conceptos de programación. Struts maneja estos formularios "multipart" de la misma forma que los formularios normales. Esto lo maneja automáticamente el marco de trabajo. Algunas veces los formularios HTML se usan para cargar otros ficheros.getUsername() %>"/> lo que es dificil de teclear correctamente.jsp: <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-html.username"/> </th> <td align="left"> <html:text property="username" size="16"/> </td> </tr> <tr> <th align="right"> <html:message key="prompt. En la siguiente sección. que genera un botón navegador de ficheros. Consideremos la siguiente página (basada en la aplicación de ejemplo incluida con Struts) llamada logon. El caso de arriba sería renderizado de esta forma usando Struts: <html:text property="username"/> sin la necesidad de refirnos explicitamente al formulario JavaBean del que se recupera el valor inicial. y puede causar problemas con editores HTML.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <html:html> <head> <title> <bean:message key="logon. pero es cosa del desarrollador manejar los ficheros entrantes.title"/> </title> <body bgcolor="white"> <html:errors/> <html:form action="/logon" focus="username"> <table border="0" width="100%"> <tr> <th align="right"> <html:message key="prompt.submit"/> </html:submit> </td> <td align="right"> <html:reset> <bean:message key="button. La mayoría de los navegadores soportan esto a través de un elemento <input type="file">. usaremos Struts para crear un simple formulario de login.reset"/> </html:reset> </td> </tr> </table> . En su lugar Struts proporciona una facilidad comprensiva para construir formularios.

se creará uno nuevo automáticamente.struts. El desarrollador de Struts proporciona la implementación Java para este bean de formulario.Etiqueta para el botón "Reset" Cuando el usuario entra.   Las banderas de error muestran cualquier mensaje de error que haya sido almacenado por un componente de lógica de negocio. basadas en este ejemplo:  La directiva taglib le dice al compilador de la página JSP donde encontrar el tag library descriptor para la librería de etiquetas Struts. La etiqueta text se renderiza como un elemento <input> de HTML del tipo "text". la aplicación puede almacenar un objeto Locale en la sesión de este usuario. para que estos valores sean internacionalizados.apache. estamos usando bean como el prefijo que identifica las etiquetas de la librería strutsbean.apache. Este Locale se usará para seleccionar mensajes en el idioma apropiado. como las peticiones. Obviamente cuando creamos un formulario multiparte estámos creando un formulario que al menos tiene un entrada del tipo "file".servlet. o prompt.action.reset .Título de la página de login. Esto se hace sencillo de implementar dando al usario una opción para elegir el idioma -.HttpServletResponse. Esta página usa varias ocurrencias de la librería de mensajes para buscar los strings de mensajes internacionalizados desde un objeto MessageResources que contiene todos los recursos de esta aplicación.Etiqueta para el botón "Submit" o button. Este bean se usa para proporcionar valores iniciales para todos los campos de entrada que tienen nombres que corresponden con nombres de propiedades del bean.ActionForm.ActionMapping.http. También asocia todos los campos que hay dentro del formulario con un FormBean con ámbito de sesión que se almacena bajo la clave logonForm. mientras el usuario teclea su password. en cuyo caso se pueden omitir el Nombre y el Tipo.http.apache. import org.do"> Please Input Text: <html:text property="myText"><br/> Please Input The File You Wish to Upload:<br/> <html:file property="myFile"><br /> <html:submit /> </html:form> El siguiente paso es crear nuestro bean ActionForm : import javax..FormFile.action. el valor actual de la propiedad username del bean correspondiente (es decir. o ninguna si no se ha almacenado ningún error. usando el nombre de la clase Java especificado.struts. En este caso también se han especificado el número de caracteres y la posición a ocupar en la ventana del navegador.submit . basándose en los atributos especificados. La etiqueta password se usa de forma similar. public class UploadForm extends ActionForm { protected String myText.password .tld" prefix="html"> <html:form action="uploadAction. import org. y "html" como el prefijo que identifica las etiquetas de la librería struts-html.simplemente cambiamos el objeto Locale almacenado. extendiendo la clase ActionForm de Struts. el valor devuelto por getUsername()). (Puedes ver más detalles en Fichero de Configuraciín para Action Mappings). . La diferencia está en que el navegador mostrará asteriscos. Las etiquetas de texto para cada botón se crean usando la librería de mensajes. Si no se encuentra un bean apropiado.title .      Manejar formularios multiparte también es sencillo. Se puede usar cualquier prefijo que deseemos. En este caso.</html:form> </body> </html:html> Los siguientes ítems ilustran las características clave del manejo de formularios en Struts.Un string para pedir el "Username:" o prompt. y todos los mensajes se modificaran automáticamente. Cuando se ejecuta esta página.Un string para pedir la "Password:" o button.struts.HttpServletRequest. Esta etiqueta se describirá más adelante. import javax. Las etiquetas submit y reset generan los botones correspondientes en la parte inferior del formulario. se deben definir las siguientes claves de mensajes en estos recursos: o logon.upload.servlet. Para que esta página funcione. import org. El primer paso para crear el formulario multiparte es utlizar la librería de etiquetas struts-html para crear la página de presentación: <%@page language="java"> <%@taglib uri="/WEB-INF/struts-html.username . El bean formulario también se puede especifiar en el fichero de configuración de Struts.. La etiqueta form renderiza un elemento <form> HTML. en lugar del valor de entrada.

protected FormFile myFile. Struts ofrece una facilidad adicional para validar los campos de entrada que ha recibido. } public void setMyFile(FormFile file) { myFile = file. header. Para utilizar esta característica. [bean] parameter recupera el valor del parámetro solicitado. option options Botones submit Campos de entrada de texto text textareas En cada caso. role. Los atributos incluyen cookie. para más información:   [logic] iterate repite su cuerpo de etiqueta una vez por cada elemento de una colección especificada (que puede ser una Enumeration. o un array de objetos). [html] img genera un elemento <img> HTML con la habilidad de modificar dinámicamente las URLs especificadas por los atributos "src" y "lowsrc" de la misma forma en que se puede hacer con <html:link>. name. y user. por eso los campos saben qué bean utilizar para inicializar los valores mostrados. a menos que utilicemos el atributo property. . Básicamente en nuestro método peform() de nuestra clase action deberíamos llamar a ((UploadForm) form). [html] link genera un elemento <a> HTML como una definición de un enlace o un hiperenlace a la URL especificada. También podemos ver los Javadocs para ActionServlet y ActionMapping para ver los distintos parámetros que podemos especificar para cambiar la forma en que se (suben) cargan los ficheros. [logic] notPresent el contrario de la etiqueta present. y evalua el contenido de los campos anidados de esta etiqueta sólo si hay un valor presente. en cuyo caso también es necesario el nombre del atributo. un Hashtable. } public FormFile getMyFile() { return myFile. property.getMyFile() para recuperar el FormFile y hacer lo que queramos con él. consulta la documentación de cada librería de etiquetas especifica. parameter. y automáticamente aplica codificación URL para mantener el estado de la sesión en la ausencia del soporte de cookies. notPresent proporciona la misma funcionalidad pero cuando el atributo especificado no está presente. } public String getMyText() { return myText. sobreesribimos el siguiente método en nuestra clase ActionForm: public ActionErrors validate(ActionMapping mapping. public void setMyText(String text) { myText = text. } } Podemos ver los Javadocs del FormFile para ver los métodos que expone para manipular y subir ficheros. Otras Útiles Etiquetas de Presentación Hay varias etiquetas útiles para crear presentaciones.     Validación Automática de Formularios Además de las interacciones entre el formulario y el bean descrita arriba. un Vector. Sólo se puede usar uno de los atributos en una ocurrencia de esta etiqueta. esta etiqueta chequea la solicitud actual. scope. junto con la Guía de Desarrolladores de Etiquetas. [logic] present dependiendo del atributo que se especifique. una etiqueta de campo debe estár anidada dentro de una etiqueta form. y define el resultado como un atributo de ámbito de página del tipo String o String[]. Tipos de Campos de Entrada Soportados Struts define etiquetas HTML para todos estos tipos de campos de entrada:            checkboxes Campos hidden Campos de entrada password Botones de radio Botones de reset Lsitas select con opciones embebidas o ítems de opciones.

y el servlet controlador procederá a llamar al método perform() de la clase Action apropiada. Luego. que pasa los valores de la clave primaria requerida como un atributo de la solicitud. Esto se usa cuando se listan las subcripciones asociadas con un usuario. linkSubscription .example. El servlet controlador almacena este array como un atributo de la solicitud disponible para usarse por la etiqueta <html:errors>. y devolverá el control al formulario de entrada (identificado por la propiedad input de este ActionMapping). que son clases que contienen las claves del mensaje de error (dentro del paquete MessageResources de la aplicación) que se deberían mostrar. La aplicación de ejemplo incluida con Struts ilustra este principio creando las siguientes etiquetas únicamente para la implementación de esta aplicación:    checkLogon . pero antes de se llame al método perform() correspondiente de la clase action. podemos usar la capacidad include de las páginas JSP para combinar los resultados en . y fue empleada en el ejemplo incluido con Struts.HttpServletRequest request).Chequea la existencia de un objeto session particular. linkUser . Composición de Páginas con Includes Crear la presentación completa de una página en un fichero JSP (con etiquetas personalizadas y beans para acceder a los datos dinámicos requeridos) es un aproximación de diseño muy común.Devuelve un ejemplar de ActionErrors conteniendo ActionError's. esta característica es totalmente opcional. y proporciona enlaces para editarlas o borrarlas. La implementación por defecto de validate() devuelve null. Otras Técnicas de Presentación Aunque el aspecto y el comportamietno de nuestra aplicación puede construirse completamente basándonos en las capacidades estándards de JSP y la librería de etiquetas de Struts.apache.Genera un hiperenalce a una página de detalles de usuario. Acceso a tópicos de discusión relacionados con este portal. para asistirnos en la creación del interface de usuario. muchas aplicaciones requieren mostrar varias porciones de distinciones lógicas de nuestra aplicación en una sóla página Por ejemplo. y el servlet controlador asumirá que no se requiere que se haga ninguna validación por parte de la clase Action. Esto se usa para capturar casos donde un usuario ha colocado un página del medio de la aplicación en su bookmark e intenta saltarse el login. El método validate() es llamado por el servlet controlador después de que se hayan rellando las propiedades del bean. que pasa los valores de la clave primaria requerida como atributos de la solicitud. reduzca los esfuerzos de mantenimiento. Sin embargo. El código fuente de estas etiquetas está en el directorio. Un indicador de "mail esperando" si nuestro portal proporciona cuentas gratuitas de correo.Genera un hiperenlace a una página de detalles para una Subscription. deberíamos considerar emplear otras técnicas que mejoren la reutilización de componentes. podría tener alguna o todas estas capacidades funcionales disponibles en la página "home" del portal:     Acceso a un motor de búsqueda para este portal. Etiquetas Personalizadas Específicas de la Aplicación Más allá del uso de las etiquetas personalizadas proporcioandas por la librería de Struts. Realiza las validaciones apropiadas y encuentra problemas -. junto con otras clases Java que son usadas por esta aplicación. y luego manejar la validación de la "lógica de negocio" desde el objeto Action. Uno o más displays "alimentadores de noticias" con los tópicos de interés personalizados desde el perfil de registro del usuario. en el paquete org. El método validate() tiene las siguientes opciones:   Realiza las validaciones apropiadas y no encuentra problemas -. y/o reduzca los errores. o si ha expirado la sesión de un usuario.struts. y reenvía el control a la página de logon si no esite. Un paquete opcional para realizar validaciones ActionForm está disponible en la web site de David Winterfeldt's. Una aproximación común es realizar validaciones iniciales usando el método validate(). es fácil crear etiquetas que sean específicas de la aplicación que estamos construyendo. una aplicación portal. El desarroolo de los distintos segmentos de esta site es sencillo si podemos dividir el trabajo y asignar los distintos segmentos a diferentes desarrolladores.Devuelve null o ejemplares de ActionErrors de longitud cero. Como se mencionó anteriormente. En las siguientes secciones se explican varias opciones. src/example.

Normalmente se utilizan dos diferentes aproximaciones para obtener estos requerimientos:   Renderizar un hiperenlace con una URL que ejecuta una solicitud Servlet. . o el argumento "id". Junto con otras cosas. Hay disponibles tres tipos de include. El código se pone en línea dentro de la otra página JSP antes de que sea compilada y por eso puede contener definitivamente más que sólo código HTML. Si está siendo renderizada una página completa. Puedes ver más detalles en la Guia del Desarrollador. // use writer to render text return(null).setContentType("text/plain").una sóla página. dinámicamente. que representa la variable string del contexto de la pagina a imprimir en la página JSP. como cartas de precios sobre una site de informe de stocks. El include de action (<jsp:include page="xxxxx" flush="true" />) se procesa en el momento de la solicitud. es muy fácil hacerlo desde un Action: response.   Otra aproximación a esto sería el uso de la librería de plantillas de etiquetas de Struts. ofreciendo varias mejoras y nuevas capacidades. Tiles está disponible en el la web site de Cedric Dumoulin. Componentes de Renderizado de Imágenes Algunas aplicaciones requieren generar imágenes dinámicamente. esto significa que podemos realizar el include condicionalmente anidandolo dentro de una etiqueta como equals usando sus atributos de parámetros La etiqueta bean:include toma un argumento "forward" que representa un nombre lógico mapeado al JSP a incluir. El código incluido en el fichero puede incluso referenciar variables declaradas antes en la página JSP exterior. y puede sacarse usando un PrintWriter. // or text/xml PrintWriter writer = response. Dibujo de Texto Algunas aplicaciones requieren que se genere texto o marcas. que los mostrará como si hubiera recibido un fichero estático. y es manejado de forma transparente por el servidor. Tiles es una alternativa a la Librería de Plantilla de Etiquetas.getWriter(). Renderizar el código HTML necesario para descargar un Applet Java que cree el gráfico necesario. Podemos configurar el gráfico selecionando los parámetros de inicialización del applet en el código de renderizado. y envia de vuelta al navegador los bytes de la imagen. o usar la etiqueta include proporcionada por Struts. El servlet usa una librería gráfica para renderizar la imagen. como XML. dependiendo de cuando queremos que ocurra la combinación de la salida:  Una directiva <%@ include file="xxxxx" %> puede incluir un fichero que contiene código Java o etiquetas JSP. selecciona el tipo de contenido apropiadamente (como a image/gif). o podemos tener que hacer que el applet haga su propia conexión al servidor para recibir estos parámetros.

Por lo tanto.xml.     Entre los problemas de diseño a recordar cuando codificamos clases Action incluimos los siguientes:     El servlet controlador crea un sólo ejemplar de nuestra clase Action. valida las propiedades del bean formulario según sea necesario. Los beans que representan el Modelo de nuestro sistema podría lanzar excepciones debido a problemas de acceso a bases de datos o a otros recursos. es hora de enfocarnos en los componentes del Controller.action.Construir los Componentes del Controlador Introducción Ahora que hemos entendido cómo construir los componentes del Modelo y de la Vista de nuestra aplicación.log("Error message text". dependiendo de cuánto tiempo necesitemos mantener estos ítems disponibles). necesitamos codificar nuestra clase Action para que opere correctamente en un entorno multi-thread. Clases Action La clase Action define dos métodos que podrían ser ejecutados dependiendo de nuestro entorno servlet: public ActionForward perform(ActionMapping mapping. pero generalmente debería realizarse llamando a un método apropiado del bean de lógica de negocio. ServletException. chequear que el usuario ha hecho el login). La mayoría de los proyectos sólo usarán la versión "HttpServletRequest".apache.Action). El principio más importante que nos ayuda en la codificación de threads seguros es usar sólo variables locales. HttpServletRequest request. Si la clase Action encuentra que no existe logon. no variables de ejemplar. Realizar el procesamiento requerido para tratar con esta solicitud (como grabar un fila de la base de datos). public ActionForward perform(ActionMapping mapping. y reenvía el control de vuelta al formulario de entrada para que se puedan corregir los errores. mediante su método perform(). En el patrón de diseño MVC/Model 2. HttpServletResponse response) throws IOException. como si estuvieramos codificando un método service() de un servlet. Las variables locales se crean en una pila que es asignada (por nuestra JVM) a cada thread solicitado. nuestras principales responsabilidades con el controlador son:     Escribir una clase Action por cada solicitud lógica que podría ser recibida (extendida desde org. Actualizar los objetos del lado del servidor que serán usados para crear la siguiente página del interface de usuario (normalmente beans del ámbio de solicitud o de sesion. ActionForm form. El fichero de configuración XML normalmente se llama struts-config. desde un bookmark). ServletException. exception). la solicitud es reenviada a la página JSP que muestra las peticiones del nombre de usuario y la password para logging on. Struts incluye un servlet que implementa la función principal de mapeo de una solicitud URI a una clase Action. Si la validación no se ha completado. . en nuestra clase Action. y la usa para todas las solicitudes. almacena las claves de los mensajes de error apropiados como un atributo de la petición. una clase Action típica implementará una lógica como ésta en su método perform():  Validar el estado actual de la sesión del usuario (por ejemplo. El objetivo de una clase Action es procesar una solicitud. Configurar un ActionMapping (en XML) por cada solicitud lógica que podría ser enviada. Si se encuentra un problema. Actualizar el fichero del descriptor de despliegue de la aplicación Web (en XML) para nuestra aplicación para que incluya los componentes Struts necesarios. y el contenedor servlet creó una nueva. y devolver un objeto ActionForward que identifica dónde se debería reenviar el control (por ejemplo a una JSP) para proporcionar la respuesta apropiada. Deberíamos atrapar dichas excpeciones en la lógica de nuestro método perform(). Devolver un objeto ActionForward apropiado que identifica la página JSP usada para generar esta respuesta. por eso no necesitamos preocuparnos de compartirlas. o en el propio servlet controlador (si estamos usando un nombre lógico global para la aplicación). Típicamente adquiriremos una referencia a dicho objeto llamando a findForward() o al objeto ActionMapping que recibimos (si estamos usando un nombre lógico normal para este mapeo). o porque la sesión ha expirado. Es decir. Esto podría ocurrir porque un usuario intente entrar "en el medio" de una aplicación (digamos. ServletResponse response) throws IOException. Esto se puede hacer mediante código lógico embebido dentro de la propia clase Action. Añadir los componentes Struts apropiados a nuestra aplicación. basada en los beans actualizados recientemente. ServletRequest request. y guardalas en el fichero de log de la aplicación (junto con el seguimiento de pila correspondiente) llamando a: servlet. ActionForm form.

Normalmente. creando los objetos apropiados de la misma forma. hay dos elementos importantes que son usados para describir nuestras acciones:  <form-beans> Esta sección contiene nuestras definiciones de beans.xml de la aplicación de ejemplo incluye las siguientes entradas de mapeo para la función "log on". Como regla general. el servlet controlador Struts necesita conocer varias cosas sobre como se debería mapear toda URI solicitada a una clase Action apropiada. o type: El nombre totalmente cualificado de la clase Java de nuestro bean de formulario. para manejar todas las solicitudes no manejadas por otros action. La forma más fácil de hacer que esto suceda es embeber la lógica funcional en la propia clase Action.El path de la URI solicitada que corresponden con la selección de este mapeo. forward . <action-mappings> Esta sección contiene nuestras definiciones de acciones. El elemento XML más exterior debe ser <struts-config>. Dentro del elemento <struts-config>. name .El nombre del bean de formulario definido en el fichero de configuración que usará este action. porque está embebido dentro de un componente (la clase Action) que está concebido para ser ejecutado en un entorno de aplicación Web. Además. esta aproximación también hace díficil re-utilizar el código de la lógica de negocio. Este formato de documento está restringido por su definición en "struts-config_1_0. asignar recursos y mantenerlos a través de las solicitudes del mismo usuario (en la misma sesión de usuario) puede causar problemas de escalabilidad. Fichero de Configuración de los Mapeos de Action ¿Cómo aprende el servlet controlador sobre los mapeos que queremos? Sería posible (pero tedioso) escribir una pequeña clase Java que simplemente ejemplarizara nuevos ejemplares de ActionMapping.El path de la URI solicitada a la que se pasa el control cuando se ha invocado su mapeo. Una Action puede dividirse en varios métodos locales. y por eso son seguras ante los threads. Usamos un elemento <action> por cada una de nuestras acciones que queramos definir. o una aproximación a emular. estas son las propiedades más importantes:       type . Oserva que las entradas para otras acciones se han dejado fuera: <struts-config> <form-beans> . La JVM maneja dichas propiedades usando la pila. Struts incluye un módulo Digester que es capaz de leer la descripción basada en XML de los mapeos deseados. Esto debería considerarse un bug en el diseño de la aplicación de ejemplo. en vez codificarla en beans de lógica de negocio independientes.  El fichero struts-config.xml. Para hacer este proceso más sencillo. es también el nombre del atributo de solicitud o sesión bajo el que se almacena este bean de formulario. que tiene los siguientes atributos importantes: o name: Un identificador único para este bean.dtd". y llamara a todos los métodos set() apropiados. Puedes encontrar más información sobre este Digester en la documentación del API La responsabilidad del desarrollador es crear un fichero XML llamado struts-config. Sólo un Action puede estar definido como por defecto dentro de una sóla aplicación. validate . porque la propia lógica de negocio está embebida dentro de las clases Action. El conocimiento requerido ha sido encapsulado en un interface Java.Seleccionado a true si este action debería ser configurado como por defecto para esta aplicación. o name: El nombre de nuestro elemento <form-bean> para usar con esta action. La aplicación de ejemplo incluida con Struts no cumple este principio. que se usará para ilustrar los requerimientos. path . o type: El nombre totalmente cualificado de la clase Java de nuestra clase Action. que será usado para referenciarlo en los correspondientes mapeos de acciones.incluso si un método del bean que hemos llamado lanza una excepción. llamado ActionMapping. en vez de una característica intrínseca de la arquitectura . Esto es una alternativa a declarar una propiedad type. mientras que todas las propiedades necesarias sean pasadas en las firmas de métodos. Deberíamos pensar en liberar esos recursos (como las conexions a una base de datos) antes de reenviar el control al componente de la Vista apropiado -. y situarlo en el directorio WEB-INF de su aplicación.Seleccionado a true si se debería llamar al método validate() de la action asociada con este mapeo. La Implementación de ActionMapping Para poder operar satisfactoriamente. Cada elemento action requiere que se definan los siguientes atributos: o path: El path a la clase action en relación al contexto de la aplicación. Además de hacer la propia clase Action dura de entender y de mantener. unknown .nombre totalmente cualificado de la clase Java que implementa la clase Action usada por este mapeo. queremos protegernos contra clases Action que son demasiado largas. Usamos un elemento <form-bean> por cada bean de formulario.

EditSubscriptionAction" name="subscriptionForm" scope="request" validate="false"> <forward name="failure" path="/mainMenu. Una sección más de buen uso es la sección <data-sources>.example.jsp" unknown="false" validate="true" /> </action-mappings> </struts-config> Primero se define el bean formulario.struts.jsp" redirect="false" /> </global-forwards> <action-mappings> <action path="/logon" type="org.example. Opcionales pero muy útiles son los elementos localizados en "forward".jsp"/> </action> Usando estas dos propiedades extras. las clases Action de la aplicación de ejemplo son casi totalmente independientes de los nombres reales de las páginas JSP que son usadas por los diseñadores.postgresql. pueden renombrarse (por ejemplo) durante un rediseño. Un bean básico de la clase "org. podemos definir cualquier propiedad de reenvío local que tenga sentido para nuestra aplicación. Si los nombres de las páginas JSP "next" estuvieran codificados dentro de las clases Action.Edit mail subscription --> <action path="/editSubscription" type="org.Driver" maxCount="4" minCount="2" password="mypassword" url="jdbc:postgresql://localhost/mydatabase" user="myusername"/> </data-sources> </struts-config> . Aquí podemos ver cómo especificar una fuente de datos para nuestra aplicación dentro de struts-config. que especifica las fuentes de datos que puede usar nuestra aplicación. porque la aplicación de ejemplo usa mapeo de extensión.example.xml: <struts-config> <data-sources> <data-source autoCommit="false" description="Example Data Source Description" driverClass="org.struts.LogonForm" es mapeado al nombre lógico "logonForm". por ejemplo actionMappingInstace. La sección "global-forwards" se usa para crear mapeos de nombres lógicos para páginas JSP usadas comunmente. muchas acciones incluyen un reenvio local "success" y/o "failure" como parte de un mapeo de Action.struts. En la aplicación de ejemplo. Como podemos ver.jsp"/> <forward name="success" path="/subscription.do). este mapeo corresponde con el path /logon (realmente. <!-. se crea un ejemplar de LogonAction (sólo la primera vez).apache.LogonAction" name="logonForm" scope="request" input="/logon.LogonForm" /> </form-beans> <global-forwards type="org. todas estas clases tendrían que ser modificadas. Cada uno de estos reenvíos está disponible a través de una llamada a nuestro ejemplar de mapeo de action.<form-bean name="logonForm" type="org.struts. Cuando se recibe una solicitud que corresponde con el path.apache. Por supuesto. Este nombre se usa como un nombre de atributo de sesión o solicitud para el bean de formulario.apache.example.apache. Las páginas.apache.findForward("logicalName"). El Servlet controlador buscará un bean de ámbito de sesión bajo la clave logonForm. con un mínimo impacto en las propias clases Action. creando y guardando un bean de la clase especificada si es necesario. la URI que especificamos en una página JSP terminaría en /logon.action.struts.ActionForward" /> <forward name="logon" path="/logon.

out en lugar de servlet log. Usando el descriptor de despliegue del la aplicación de ejemplo como guía. Los corchetes cuadrados describen los valores por defecto que se asumen si no proporcionamos un valor para el parámetro de inicialización.apache.apache. [org. podría ser sobreescrito por un servlet re-enviado o una página JSP.ApplicationMapping </param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> Los parámetros de inicialización soportados por el servlet controlador se describen abajo.          application .PropertyMessageResourcesFactory]. [true] mapping .Descriptor de Despliegue de la Aplicación Web El paso final en la configuración de la aplicación es configurar el descriptor de despliegue (almacenado en el fichero WEBINF/web. Podríamos usar aquí dos clases de conveniencia:   . factory .apache. [org.apache.ActionFormBean]. Dicha entrada se podría parecer a esto: <servlet> <servlet-name>action</servlet-name> <servlet-class> org.El nombre de la clase Java de la implementación del ActionMapping a utilizar. o org.ActionForward que por defecto pone la propiead redirect a false (lo mismo que el valor por defecto de ActionForward).action.apache.Locale apropiado (bajo la clave estándard indentificada por Action.el nombre de la clase Java de la implemetnación de ActionForward a utilizar.action. [org. Configurar el Ejemplar de Action Servlet Añadimos una entrada definiendo el propio servlet action.apache.xml].El nivel de detalle de depuración para este servlet.util. que sale por System.action.struts.xml) para incluir todos los componentes Struts que son necesarios.ApplicationResources </param-value> </init-param> <init-param> <param-name>config</param-name> <param-value> /WEB-INF/struts-config.El nivel de detalles de depuración para el Digester que utilizamos en initMapping().struts.El nombre de la clase Java para la clase base del paquete de recursos de la aplicación. que controla cuanta información se pone en el log.example. content . [org. [NONE].struts.[/WEB-INF/strutsconfig.ActionForward].ForwardingActionForward .Subclase de org.action. [text/html]. y hay una sesión de usuario.apache.struts. [0].struts.RedirectingActionForward .Subclase de org.util. config . veremos que se necesitan crear o modificar la siguientes entradas.example.apache.apache.Tipo de contenido por defecto y codificación de caracteres a seleccionar en cada respuesta.Si se selecciona a true.struts. formBean .El nombre de la clase Java del MessageResourcesFactory usado para crear el objeto MessageResources de la aplicación.ActionMapping]. Podríamos usar aquí dos clases de conveniencia: o org. [4096].ActionForward que por defecto pone la propiedad redirect a true. indentifica y almacena un objeto java. bufferSize .action. detail .struts. junto con los parámetros de inicialización apropiados.struts. forward .LOCALE_KEY) en la sesión de usuario si no hay ya un objeto Locale. [0]. locale .struts. debug .xml </param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>2</param-value> </init-param> <init-param> <param-name>mapping</param-name> <param-value> org.action.apache.action.El nombre de la clase Java de la implementación de ActionFormBean a utilizar.apache.El tamaño del buffer de entrada usado para procesar uploads de ficheros.Path relativo al contexto del recurso XML que contiene nuestra información de configuración.struts.struts.action.ActionServlet </servlet-class> <init-param> <param-name>application</param-name> <param-value> org.

o "G".apache. Actualmente hay cuatro librerías que vienen con Struts. multipartClass . o Configurar el Mapeo del Servlet Action Nota: El material de esta sección no es específico de Struts. [org.com/myapplication/logon.Subclase de org.ActionMapping que por defecto deja la propiedad scope a "session".action. Por ejemplo.com/myapplication/execute/logon donde /myapplication es el path de contexto bajo el que se ha desplegado nuestra aplicación. se renvian las URIs solicitadas al servlet action basándose en el hecho de que la URI termine en un punto seguido por un conjunto defindo por caracteres.ActionMapping que por defecto deja la propiedad scope a "request".struts. Esta sección describe los significados más comunes de configuración de una aplicación Struts. Puede expresarse como un número seguido por una K" "M". tempDir .upload. de las cabeceras y de los parámetros. debemos añadir una entrada definiendo la librería de etiquetas Struts.struts. La correspondencia de prefijo significa que queremos que todas las URLs que empiecen con (después de la parte del path de contexto) un valor particular sean pasadas a este servlet. nocache .apache.do</url-pattern> </servlet-mapping> y una URI que corresponda con el path /logon descrito anteriormente se parecería a esto: http://www. [false]. La configuración del mapeo de servlets está definida en la Java Servlet Specification.action. Dicha entrada se podría parecer a esto: <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/execute/*</url-pattern> </servlet-mapping> lo que significa que una URI que coincida con el path /logon descrito anteriormente podría parecerse a esto: http://www.El tamaño máximo (en bytes) para que un ficheo sea aceptado para upload. (Igual que el valor por defecto de ActionMapping).correspondencia de prefijo y correspondencia de extensión.action.mycompany. null . maxFileSize .apache.       org.¿Estámos suando el nuevo formato de fichero de configuración? [true].action. el servlet de procesamiento JSP está mapeado al patrón *. [250M]. La librería struts-bean contiene etiquetas útiles para acceder a los beans y sus propiedades.do (que implica "hacer algo"). o org. configura los recursos de nuestra aplicación a devolver null si se usa una clave de mensaje desconocida.Si se selecciona a true.jsp para que sea llamado cada vez que se solicite una página JSP.Subclase de org.apache. . respectivamente. validate . que serán interpretadas como kilobytes. De otra forma.do Configurar la Librería de Etiquetas de Struts Luego.struts.El directorio de trabajo temporal usado cuando se procesan uploads de ficheros. añade cabeceras HTTP a cada respuesta para evitar que el navegador almacene en el cahé cualquier respuesta generado o reenviada. [true]. en el mapeo por extensión. Para usar la extensión *.RequestActionMapping .SessionActionMapping .apache. se devolverá un mensaje de error incluyendo la clave errónea. así como para definir nuevos beans (basados en esos accesores) que son accesibles para el resto de la página mediante variables de scripting y atributos de ámbito de página.Si se selecciona a true.struts.DiskMultipartRequestHandler]. También se proporcionan mecanismos convenientes para crear nuevos beans basados en el valor de una cookie. megabytes. la entrada de mapeo se podría parecer a esta: <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*. Por otro lado. validating . o gigabytes. [El directorio de trabajo proporcionado para esta aplicación web como atributo contexto del servlet]. Hay dos aproximaciones comunes para definir las URLS que serán procesadas por el servlet controlador -.mycompany.El nombre totalmente cualificado de la clase de la implementación de MultipartRequestHandler usado para procesar uploads de ficheros.struts.¿Deberíamos usar un analizador con validación XML para procesar el fichero de configuración (altamente recomendado? [true].

Abajo podemos ver cómo se definirían todas las librerías de etiquetas para usarlas en nuestra aplicación.jar (y todos los otros ficheros commons-*. .tld </taglib-location> </taglib> <taglib> <taglib-uri> /WEB-INF/struts-template.tld </taglib-uri> <taglib-location> /WEB-INF/struts-template. La librería struts-template contiene etiquetas que definen un mecanismo de plantillas.tld </taglib-location> </taglib> <taglib> <taglib-uri> /WEB-INF/struts-html. en realidad. en vez de en algún lugar exterior en Internet). La librería struts-logic contiene etiquetas que son útiles para manejar la generación condicional de salida de texto.jar) en nuestro directorio WEB-INF/lib. Añadir Componentes Struts a nuestra Aplicación Para usar Struts. y copiar struts.tld </taglib-uri> <taglib-location> /WEB-INF/struts-logic. sólo deberíamos especificar las librerías que vayamos a utilizar: <taglib> <taglib-uri> /WEB-INF/struts-bean.tld que necesitamos en nuestro directorio WEB-INF. así como otras etiquetas generalmente útiles en la creación de interfaces de usuario basados en HTML.La librería struts-html contiene etiquetas para crear formularios de entrada struts.tld </taglib-uri> <taglib-location> /WEB-INF/struts-html. hacer bucles sobre colecciones de objetos para generación repetitiva de salida de texto y control del flujo de la aplicación.tld </taglib-uri> <taglib-location> /WEB-INF/struts-bean.tld </taglib-location> </taglib> <taglib> <taglib-uri> /WEB-INF/struts-logic. debemos copiar los ficheros .tld </taglib-location> </taglib> Esto le dice al sistema JSP donde encontrar el descritor de librería de etiqueta para esta librería (en nuestro directorio WEBINF de la aplicación.

Sign up to vote on this title
UsefulNot useful