INTRODUCCIÓN Struts es una herramienta de soporte para el desarrollo de aplicaciones Web que sigue el patrón MVC bajo la plataforma J2EE (Java 2, Enterprise Edition), que tiene la siguiente forma: En una aplicación estándar Java EE web, el cliente presenta información al servidor por medio de un formulario web. Dicha información se envía a un servlet de Java que procesa, interactúa con una base de datos y genera un HTML con formato de respuesta, o una página JSP, en la que se mezcla el código HTML y Java para lograr el mismo resultado. Ninguno de estos enfoques son óptimos en proyectos relativamente grandes, ya que la unión entre la presentación y la lógica de la aplicación provoca un mantenimiento complicado. El objetivo de Struts es separar el modelo (lógica de la aplicación) de la vista (páginas HTML) y del controlador (unión entre la vista y el modelo). Struts proporciona el controlador por medio de un servlet conocido como ActionServlet que facilita la escritura de las plantillas para la vista o capa de presentación. El programador de aplicaciones web es responsable de escribir el código del modelo, y para la creación de una struts-config.xml archivo central de struts-config.xml que une modelo, vista y controlador. Las peticiones del cliente se envían al controlador en forma de "actions" definidas en el archivo de configuración. Cuando el controlador recibe una petición llama al action correspondiente, que actúa conjuntamente con la aplicación concreta del modelo. Este modelo devuelve un "ActionForward", que es una cadena que indica la página de salida que va a ser devuelta al cliente. Para leer y escribir el contenido de la página a devolver se hace uso de una potente librería de etiquetas, sin tener que hacer uso de ningún código Java. Componentes Como podemos ver, las aplicaciones Struts residen en un contenedor Web y pueden hacer uso de los servicios proporcionados por el contenedor, como puede ser el manejo de peticiones HTTP o HTTPS. Esto permite al desarrollador olvidarse de la lógica de negocio. Arquitectura MVC Las clases que proporciona Struts a la capa C son las siguientes: - ActionServlet: clase (no abstracta) que extiende de java.servlet.http.HttpServlet y es la responsable del empaquetado y enrutado del tráfico HTTP hacia el manejador apropiado dentro del entorno Struts. - RequestProcessor: clase que permite desacoplar el proceso de petición del ActionServlet y así poder modificar cómo se procesa la petición. - Action: clase que independiza la petición del cliente del modelo de negocio. - ActionMapping: clase que representa una acción de mapeado que se define en el fichero de configuración de Struts, indicando al controlador qué instancia del action se debe invocar en cada petición. - ActionForward: clase que representa al destino al cual el controlador debe enviar el control una vez que el action se haya completado. Con respecto de la capa M, Struts no fue diseñado para trabajar con ella. Sin embargo, recibirá información de esta capa (aunque no sepa cómo está implementada). Así, la mejor forma de solucionar cómo Struts se comunica con la capa de negocio de forma que sea completamente independiente de la tecnología de implementación de ésta, es utilizar un patrón de diseño, como por ejemplo DTOs (Data Transfer Objects), también llamados Value Objects (VO). La idea es que Struts reciba la información en forma de vistas (VOs), pero no sepa cómo se han creado esas vistas. Para ello también necesitaremos implementar un nuevo patrón de diseño muy conocido, el Business Delegate. Con este patrón, crearemos un servicio perteneciente a la capa de negocio, que servirá de nexo de unión con la capa de control y será a través del cual Struts pedirá y recibirá los únicos objetos que entiende y con los que sabe trabajar: los VOs. Por el otro lado, la capa de negocio sólo sabrá que puede recibir peticiones del servicio de acceso a BD a través de JDBC y devolverá VOs, sin importarle ni quién los pide ni quién los usa a continuación (no os preocupéis que con los ejemplos se verá mucho más claro). Por último, con respecto a la capa V, los elementos de los que hace uso Struts son los siguientes: - HTML - Value Objects (vistas) - ActionForms, clase que permite pasar datos de entrada hacia delante y hacia atrás entre el usuario y la capa de negocio. - JavaServer Pages - Struts Tags (librería de etiquetas) - Otros recursos Java El funcionamiento del Framework de Struts es el siguiente: 1. El usuario realiza una petición. 2. Cada petición está asociada a una acción que contiene la regla de negocio particular. 3. La acción suele necesitar un conjunto de datos que se encapsulan dentro de un objeto llamado Form (clase física o elemento general con el comportamiento definido en el fichero de configuración). 4. Los datos se pueden validar y si la validación falla se puede volver a mostrar el formulario de entrada. 5. Una vez ejecutada la acción, puede que el resultado sea favorable o desfavorable por lo que se delega sobre distintos elementos de presentación en cada caso. 6. Todo mensaje mostrado puede sacarse a un fichero de recursos para favorecer su mantenimiento y la internacionalización de las aplicaciones. 7. Cada elemento se construye por separado y se relacionan en el fichero strutsconfig.xml. Las características de Struts son las siguientes: - Configuración del control centralizada. - Las interrelaciones entre Acciones (actions) y página u otras acciones se especifican por medio de tablas XML, en lugar de codificarlas en los programas o páginas. - Se invoca una acción (clase) que está mapeada en Struts. - El mapeo de acciones se realiza en el archivo struts-config.xml - Utiliza librería de entidades para facilitar las operaciones que realizan las páginas JSP. - Contiene herramientas para validación de campos de plantillas bajo varios esquemas que van desde validaciones locales en la propia página hasta validaciones globales a nivel de acciones. - Los componentes de aplicación son el mecanismo para compartir información bidireccionalmente entre el usuario de la aplicación y las acciones del modelo. - Permite que el desarrollador se concentre en el diseño de aplicaciones complejas como una serie simple de componentes del Modelo y de la vista intercomunicados por un control centralizado. Diseñando de esta manera puede obtenerse una aplicación más consistente y más fácil de mantener. ESTRUCTURA. FLUJO DE NAVEGACION STRUTS1 Struts es una capa de control flexible, basado en tecnologías estándar, como Java Servlets, JavaBeans, ResourceBundles, y XML, así como varios paquetes de Apache Commons, como BeanUtils y la cadena de responsabilidades. El marco ayuda a crear un entorno de desarrollo extensible para su aplicación, basado en estándares publicados y patrones de diseño probados. El marco de Struts1 proporciona su propio componente de controlador de red y se integra con otras tecnologías para proporcionar el modelo y la vista. Para el modelo, el marco puede interactuar con el estándar de las tecnologías de acceso a datos, como JDBC y EJB, así como la mayoría de los paquetes de terceros, como Hibernate o iBATIS. Para la vista, el marco funciona bien con JavaServer Pages, incluyendo JSTL y JSF, así como XSLT y otros sistemas de presentación. Cuando se recibe una petición, el controlador invoca una clase de acción. La consulta a la clase de acción con el modelo (o, preferiblemente, una fachada que representa el modelo) para examinar o actualizar el estado de la aplicación. El marco proporciona una clase ActionForm para ayudar a la transferencia de datos entre el modelo y la vista. En la mayoría de los casos, el modelo se representa como un conjunto de JavaBeans. Normalmente, los desarrolladores utilizar BeanUtils para transferir datos entre ActionForms y los objetos de modelo. El fichero de configuración de Struts1 tiene la siguiente forma: <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"> <struts-config> <form-beans> <form-bean name="logonForm" type="app.LogonForm"/> </form-beans> <action-mappings> <action path="/Welcome" forward="/pages/Welcome.jsp"/> <action path="/Logon" forward="/pages/Logon.jsp"/> <action path="/LogonSubmit" type="app.LogonAction" name="logonForm" scope="request" validate="true" input="/pages/Logon.jsp"> <forward name="success" path="/pages/Welcome.jsp"/> <forward name="failure" path="/pages/Logon.jsp"/> </action> <action path="/Logoff" type="app.LogoffAction"> <forward name="success" path="/pages/Logoff.jsp"/> </action> </action-mappings> <message-resources parameter="resources.application"/> </struts-config> Hay varios otros recursos que puede especificar en el archivo de configuración del marco. Puede especificar las validaciones para la ActionForms en un descriptor XML, con el validador de Struts. Struts es extensible. Cada clase desplegada por el marco puede ser sustituida por su propia clase por defecto. Las propiedades de la clase por defecto se pueden configurar. Esta es una razón por qué hay tantas extensiones contribuyente. Ofrecemos el marco de base, pero aún se puede escribir una aplicación de su camino. STRUTS2 Apache Struts 2 es un elegante marco extensible para la creación de aplicaciones empresariales de web de Java. El marco está diseñado para simplificar el ciclo de desarrollo completo, desde la construcción, para la implementación y el mantenimiento de las aplicaciones a lo largo del tiempo. Apache Struts 2 fue originalmente conocido como WebWork 2. Después de trabajar de forma independiente por varios años, la WebWork Struts y las comunidades se unieron para crear Struts2. Esta nueva versión de Struts es más fácil de usar y más cercana que la anterior. STRUTS1 VS STRUTS2 Clase action Struts1 extiende la clase abstracta por su clase de acción. El problema con Struts1 es que utiliza dichas clases en lugar de las propias interfaces. En cambio, en Struts2, una clase Action implementa una interfaz de actions, junto con otras interfaces de uso opcional y servicios personalizados. Al mismo tiempo, Struts2 ofrece una clase ActionSupport que implementa las interfaces de uso común. Aunque no se necesite una interfaz de actions, cualquier objeto POJO junto con el propio ejecutable puede ser utilizado como un objeto actions de Struts2. Modelo de procesos. En Struts1, los actions son únicos, por lo tanto que deben ser hilos de ejecución seguros, ya que sólo una instancia de una clase se encarga de todas las solicitudes de esa acción. La estrategia de Singleton restringe a las acciones de Struts1 y requiere un cuidado especial para generar el hilo de acción de los recursos de seguridad o sincronizados, dentro del desarrollo de aplicaciones. En Struts2 no se necesitan hilos de ejecución seguros ya que se crea una instancia distinta para cada solicitud. Un contenedor de servlets genera muchos objetos para las respuestas, y un objeto más no implica una penalización en el rendimiento ni implica un gran aumento del recolector de basura. Dependencia de Servlet. Las acciones dependen de la API de Servlet ya que tanto HttpServletRequest como HttpServletResponse utilizan un método de ejecución cuando el action se invoca desde Struts1. Los contenedores se utilizan en los actions de Struts2 como un par. Los Servlets se representan como sencillos Maps que permiten que los actions se puedan analizar de forma aislada. Los actions de Struts2 pueden acceder tanto a la solicitud original como a la respuesta. Testeabilidad. Las aplicaciones de Struts1 tienen problemas para hacer pruebas ya que el método de ejecución utiliza la API de Servlet. El TestCase de Struts proporciona un conjunto de objets para poder probar la aplicación de Struts1. En cambio, para probar los actions de Struts2 se hacen uso de las propiedades que nos facilita, y se pueden llamar a los distintos métodos. Los datos de entrada de Struts1 se reciben mediante la creación de un objeto del tipo ActionFrom. Struts2 necesita tanto las propiedades de actions como las de entrada, eliminando la necesidad de un objeto de la intermedio. Valores obligatorios en las vistas. Struts 1 une los objetos en el contexto de la página utilizando el mecanismo de JSP estándar. En cambio, Struts 2 utiliza una tecnología ValueStack para acceder a los valores de los taglibs sin acoplar la vista al objeto. La estrategia de ValueStack permite la reutilización de visitas a través de una amplia gama de tipos, con las mismas propiedades. Conversión de tipos. Las propiedades de los ActionForm de Struts1 son en forma de cadena generalmente, por lo que los Commons-Beanutils son muy utilizados para la conversión de tipos, y los conversores son por clase y no configurables. En Struts 2 se utiliza OGNL para la conversión de tipo y conversores para convertir tanto los tipos de objetos básicos como los primitivos. Validación. Struts 1 utiliza la validación manual que se realiza a través de un método de validación en el ActionForm, o mediante una ampliación de la Validator Commons. Las clases pueden tener diferentes contextos de validación dentro de la misma clase, mientras que el encadenamiento de las validaciones en los sub-objetos no está permitido. Struts 2 permite la validación manual que se realiza mediante el método de validación y el marco de validación XWork. Este marco de validación permite el encadenamiento de las validaciones en sub-propiedades con las validaciones definidas para el tipo de propiedades de la clase y el contexto de validación.