Documento 367062

Anuncio
Anexo Struts
ANEXO: STRUTS
Struts es un framework MVC desarrollado dentro de la Apache Software Foundation que
proporciona soporte a la creación de las capas vista y controlador de aplicaciones web basadas
en la arquitectura Model2. Está basado en tecnologías estándar como Servlets, JavaBeans y
XML.
Struts proporciona un controlador que se integra con una vista realizada con páginas JSP,
incluyendo JSTL. Este controlador evita la creación de servlets y delega en acciones creadas
por el desarrollador, simplificando sobremanera el desarrollo de aplicaciones web.
En cuanto a la capa vista, Struts permite utilizar entre otras tecnologías páginas JSP para la
realización del interfaz. Para facilitar las tareas comunes en la creación de esta capa existen
una serie de tecnologías que se integran con Struts:

Struts taglib, una librería de etiquetas que proporciona numerosa funcionalidad
evitando el escribir código Java en las páginas JSP.

JSTL, la librería de etiquetas estándar de Java que añade funcionalidades a la librería
de tags de Struts y sustituye alguna de las ya presentes.

Tiles, una extensión que permite dividir las páginas JSP en componentes reusables
para la construcción del interfaz.

Struts Validator, proporciona validación de los formularios basándose en reglas
fácilmente configurables.

StrutsTestCase para el desarrollo de casos de prueba.

Struts Menú, un proyecto que basándose en un fichero de configuración genera
vistosos menús.

xDoclets para struts que permite la generación automática de datos del fichero de
configuración de struts a partir de javadoc de las clases de struts.

CSS, hojas de estilo en cascada, que permite la realización de interfaces web de mayor
calidad y separa mejor la presentación de los datos.
Seguidamente se van a definir un conjunto de buenas prácticas que ayuden a minimizar
problemas de desarrollo y mantenimiento, además de mejorar la calidad y rendimiento del
software desarrollado.
1.1
Funcionamiento de Struts
El punto fuerte del framework Struts es su implementación de la capa de control. La finalidad
de Struts es proveer de clases y métodos que disminuyan el trabajo y la complejidad de dicha
capa y no se ocupa de ningún modo de las otras dos capas del modelo que pueden ser
desarrolladas con múltiples tecnologías.
Para ello Struts se apoya fundamentalmente en un fichero de configuración, en dos tipos de
clases y en un servlet controlador:
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 1
Anexo Struts

Clases que heredan de ActionForm: estas clases son java beans que contienen una
propiedad con sus correspondientes métodos get y set por cada campo de formulario
que se recogerá en las peticiones, también disponen de un método que es interesante
mencionar, el método validate, este método es llamado antes de procesar cualquier
acción y se puede sobrescribir para realizar distintas validaciones sobre los dantos
introducidos por el usuario.

Clases que heredan de Action: estas clases son clases java estándar multi-hilo que
procesan la acción solicitada, son las encargadas de interactuar con la capa de
negocio y reciben como uno de sus parámetros a la clase ActionForm en caso de
haberla.

El servlet controlador es la clase RequestProcessor, TilesRequestProcessor en caso
de usar el módulo de Tiles, este servlet se encarga de recibir las petición del
navegador, y de devolver las páginas adecuadas a este según el resultado de las
acciones, en muchas ocasiones es interesante hacer uso de la herencia para poder
sobrescribir algunos métodos muy interesantes de este Servlet como son el método
proccessRoles en el que se suelen realizar las validaciones de autentificación y
autorización de usuarios o el método proccessActionPerform que se encarga de llamar
a la clase de acción adecuada.

El fichero de configuración de Struts, comúnmente conocido como struts-config.xml
contiene la declaración de las clases ActionForm, redirecciones, excepciones globales
y de los llamados action-mapping que son la definición del comportamiento que ha de
seguir el servlet controlador ante las peticiones del navegador y las respuestas de las
acciones y validaciones de formularios.
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 2
Anexo Struts
En las siguientes capturas se muestra un ejemplo sencillo de configuración en struts-config.xml
de dos acciones que hacen uso de un ActionForm:
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 3
Anexo Struts
En el siguiente esquema muestra como es procesada una petición del navegador en una
aplicación desarrollada bajo Struts:
El gráfico nos indica que se realizan los siguientes pasos entre el momento en el que el
navegador hace la solicitud y recibe la página.
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 4
Anexo Struts
El navegador envía la solicitud, el Servlet Controlador recibe la petición y consulta el fichero de
configuración de struts, en este punto se validan las credenciales y permisos del usuario en
caso de haber sobrescrito el método validateRoles de controlador. Si el usuario no tiene
credenciales o permisos para ejecutar la acción solicitada se servirá directamente una página
de error (punto 7 del diagrama).
En caso de que las credenciales y permisos sean correctos, o en caso de que no se estén
comprobando, el servlet controlador verificará si la página tiene asociado algún formulario. En
caso de ser así se encargará de llamar a los métodos set de cada una de las propiedades que
se corresponda con los campos del formulario y llamará al método validate de la clase de
actionForm. Si se obtienen errores retornará la página de introducción de datos con los
mensajes de error apropiados, en caso de que todo sea correcto llamará desde el método
proccessActionPerform a la acción solicitada. Está realizará las operaciones necesarias
llamando a las clases de negocio y retornará un objeto de redirección (que normalmente está
definido en el fichero de configuración) indicando qué acción se ha de ejecutar. Esta acción
suele ser una redirección a la vista correspondiente pero puede ser otra acción encadenada lo
que permite una mayor modularización y reutilización de Acciones más sencillas.
Como se puede observar existe un punto (número 8) en el que la capa de vista accede al
modelo, dichas operaciones han de ser únicamente operaciones de consulta de datos.
1.2
Uso correcto de Struts
En este apartado del documento se intentará prevenir sobre los errores que se suelen cometer
con más frecuencia en el desarrollo de aplicaciones bajo Struts así como recomendar ciertas
prácticas que facilitan el mantenimiento y organización de la aplicación,
Uno de los errores más comunes en Struts y en casi cualquier modelo MVC es la inclusión del
código perteneciente a una capa, en objetos pertenecientes a otra, por ejemplo introducir
código de control o incluso de negocio dentro de los JSPs, para prevenir este problema el
programador ha de conocer la filosofía del modelo MVC y tener bien identificados los objetos
pertenecientes a cada una de las tres capas, como guías generales se pueden seguir las
siguientes reglas:

Los JSPs nunca han de incluir código relacionado con el control del flujo de la
aplicación, nunca se debe llamar directamente a otras páginas desde un JSP, en vez
de eso se ha de llamar a una acción que puede ser un simple forward o un complejo
grupo de acciones encadenadas, tampoco ha de relacionarse con la capa de negocio,
la única excepción es la consulta de datos que van a ser mostrados en la página.

La capa de control está formada por el conjunto de clases que heredan de las clases
Action, ActionForm así como el servlet controlador, en estas clases nunca se deben
incluir decisiones de visualización ni de negocio, el acceso al modelo de datos se debe
efectuar desde clases de la capa de negocio que serán llamadas desde las clases de
acción.

La capa de Negocio está formada por aquellas clases que se encargan de realizar las
operaciones sobre el modelo de datos.
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 5
Anexo Struts
Un ejemplo en el que se diese de alta un empleado a través de un formulario podría estar
compuesto por las siguientes clases y JSPs:
CAPA DE MODELO:
o
BeanEmpleado.java - java bean de persistencia de hibernate.
o
Empleado.java - esta clase provee de métodos público que realizan las
operaciones necesarias sobre la clase de persistencia.
CAPA DE CONTROL:
o
EmpleadoActionForm.java - esta clase posee las propiedades y métodos
necesarios para recoger y validar los datos introducidos desde el formulario.
o
AltaEmpleadoAction.java - esta clase realiza el alta llamando a un método de
la clase Empleado y se encarga de la navegación retornando éxito o fracaso.
CAPA DE VISTA:
o
altaEmpleadoForm.jsp - este jsp muestra un formulario con los campos que es
necesario rellenar para completar un alta de empleado, también muestra los
errores de validación retornados por el servlet controlador en caso de haberlos.
o
existo.jsp - este jsp muestra un mensaje de éxito de la operación que se ha
realizado.
o
error.jsp - este jsp se encarga de mostrar los errores no relacionados con la
validación de datos.
Uno de los problemas a los que se enfrentan las aplicaciones de gran tamaño es la gran
cantidad de código duplicado que se puede dar en las clases de control, para evitar esto en la
medida de lo posible, manteniendo una buena modularidad de las mismas y facilidad de
mantenimiento se recomiendan las siguientes prácticas:

Uso de una clase de acción para cada una de las acciones que se realizan en la
aplicación, esto simplifica notablemente el mantenimiento de las acciones aunque
genera un mayor número de clases de control, es muy normal que se detecten
fragmentos de código que se repiten en dichas clases, esto puede ser subsanado
heredando de clases propias que a su vez hereden de la clase Action de Struts en vez
de hacerlo directamente, esta/s clases de las que nuestras verdaderas acciones
heredarán pueden contener aquellas operaciones que realizamos repetidamente en las
clases de acción.

El caso inverso suele ser adecuado para el desarrollo de los ActionForm, es
conveniente desarrollar un solo ActionForm para cada Objeto del modelo de datos con
todas las propiedades necesarias en los distintos formularios que actúan sobre él en
vez de desarrollar un ActionForm para cada uno de los formularios dado que en la
mayoría de ocasiones existe un gran número de campos duplicados, el ejemplo más
claro es las operaciones de inserción y modificación de entidades, en estos casos
ambos formularios JSP suelen componerse de los mismos campos.
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 6
Anexo Struts
Algunos de los errores más comunes y que más problemas pueden causar debido a su difícil
detección es la utilización de variables estáticas en las clases de acción, el programador ha de
tener presente que las clases de acción son multi-hilo y la misma instancia puede ser utilizada
por la aplicación para resolver peticiones distintas, este grave problema no puede ser
detectado en los casos prueba y es prácticamente imposible de reproducir en un entorno de
desarrollo o integración, es por ello que el desarrollador ha de tener sumo cuidado de no usar
este tipo de variables dentro de sus clases de acción.
Así mismo el buen uso del control de errores es determinante a la hora del buen
funcionamiento y robustez de una aplicación, como norma general se han de considerar los
errores según su procedencia y gravedad, una primera división se puede observar entre los
errores producidos en la capa del modelo y la capa de control, los errores de la capa de modelo
o de negocio han de ser relanzados y el peso del control de los mismos ha de recaer sobre las
clases de acción de la aplicación mediante los mecanismos que provee Struts.
Ahora hemos de distinguir entre los errores de validación y los errores de acción, los errores de
validación han de detectarse en el método validate de nuestros ActionForm, las acciones nunca
se deben recibir datos erróneos o sin validar, estos errores han de ser añadidos al objeto
ActionErrors que retorna el método validate de nuestro ActionForm al servlet controlador, este
se encargará de volver a mostrar el formulario de introducción de datos con los mensajes
adecuados. Los errores de acción ya sean excepciones relanzadas desde la capa de negocio o
errores de lógica han de ser categorizados según su gravedad y añadidos al objeto
ActionMessages que provee Struts según su nivel de gravedad (información, alerta, error o
fatal) y retornar el objeto de redirección adecuado (volver al formulario, a una página de éxito, a
una de error …)
Así mismo se hace necesario en la mayoría de aplicaciones actuales un buen control del
acceso y permisos de los usuarios, Struts se apoya en el sistema de autentificación y
autorización basado en roles de Java (JAAS) aunque es posible implementar otras
aproximaciones como SingleSignOn.
En cualquiera de los dos casos es recomendable implementar dichos controles de acceso y
permiso basándose en el método processRoles() de nuestro servlet controlador, para ello
crearemos una clase que extienda de RequestProcessor (o TilesRequestProcessor en caso de
usar Tiles) y que sobrescriba dicho método, en el realizaremos las comprobaciones necesarias,
normalmente validar que el usuario está autentificado en el sistema y validar que posee
permisos para ejecutar la acción solicitada, dentro del fichero de configuración de struts
podemos definir un atributo roles para cada action con una lista de los roles que deseamos que
tenga permisos para ejecutar dicha acción.
En caso de no cumplir los requisitos para ejecutar dicha acción lanzaremos una excepción
propia que definiremos como excepción global en nuestro fichero de configuración de struts y
que mostrará automáticamente una página de error, nuestra página de login o cualquiera que
le indiquemos.
Para validación de permisos sobre los objetos de datos o sobre determinados campos de
formularios Struts no provee de ningún sistema lo recomendable en estos casos es
implementar dicha lógica en los propios beans de datos para el primer caso y en la propia vista
en el segundo.
Una de las dudas que surgen al desarrollador durante la implementación de un componente es
si un ActionForm debe estar declarado en contexto de request, session o application, La
recomendación es utilizar siempre ActionForms en contexto de request, esta recomendación
solo ha de saltarse en raras excepciones en las que dicho ActionForm va a tener un uso muy
intensivo y mantenerlo en contexto de sesión mejoraría notablemente el rendimiento de la
aplicación, en cuyo caso nos asalta la duda de cómo destruirlo cuando ya no es necesario, esta
destrucción puede realizarse de dos maneras:
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 7
Anexo Struts

La primera es guardar en un HashMap en sesión las referencias a los ActionForms de
sesión, extender la clase RequestProcessor y destruir los ActionForms de sesión más
antiguos durante las distintas peticiones.

Otra forma es destruir todos los ActionForms de sesión cuando se acceda a nueva
operación de negocio (por ejemplo desde un menú lateral)
Las siguientes recomendaciones se refieren al control de la navegación

El uso de global-forwards para redirecciones de páginas habituales hace más fácil el
desarrollo y mantenimiento de las redirecciones y navegaciones más comunes.
<global-forwards>
<forward name="sessionError" path="/login.tiles" />
</global-forwards>

Crear clases que hereden de ExceptionHandler para manejar y redireccionar las
excepciones más comunes como las de validación de usuarios, fallos en la conexión a
BD, etc…
<global-exceptions>
<exception key="global.error.Message" type="java.lang.Exception"
handler="package.CustomExceptionHandler” path="/error.tiles"/>
</global-exceptions>

Usar ForwarAction para hacer redirecciones simples de una vista a otra que no
requieran acciones, con ello evitamos llamadas directas a páginas desde la capa de
vista, manteniendo la lógica de navegación en la capa de control.
<action path="/home" parameter="/home.tiles"
type="org.apache.struts.actions.ForwardAction"
scope="request"
validate="false">
</action>
La validación de datos introducidos por el usuario suele ser una de las partes del desarrollo que
más trabajo puede requerir, además, su mala implementación suele ser en gran medida la
culpable de las inconsistencias en las bases de datos, Struts posee una extensión fácilmente
configurable llamada struts-validator, este plugin de Struts permite definir validaciones de datos
de las propiedades de los ActionForms en un fichero de xml, para que estas reglas tengan
efecto hemos de hacer que nuestros ActionForms hereden de la clase ValidatorActionForm,
configurar dichas reglas mediante un lenguaje de expresiones dentro del XML de configuración
e incluir los mensajes de error en nuestro fichero de recursos. Además estas validaciones no
solo son realizadas en el servidor si no que puede generarse automáticamente código
javascript mediante el uso de una taglib indicando el nombre del ValidatorActionForm y una
sentencia javascript en el evento onSubmit del elemento <html:form> esta extensión de Struts
permite por tanto una gran flexibilidad y fácil manejo de las validaciones de entrada de datos en
los formularios y relega el uso del método validate de la clase ValidatorActionForm a su uso
para comprobaciones más específicas.
Otra tecnología que es interesante estudiar es el uso de xDoclets para struts, xDoclets permite
generar el fichero de configuración de struts a partir de una sintaxis específica dentro del
javaDoc de las clases de Acción, ActionForm, clases de excepción, etc… debido a la
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 8
Anexo Struts
naturaleza del fichero se hace necesario el uso de ficheros de configuración generados
manualmente para su posterior mezcla automática con los datos generados por xDoclets por lo
que la decisión de usar xDoclets como herramienta complementaria es más arbitraria que por
razones de rendimiento, mejora o ahorro de tiempo.
Por ultimo destacar la importancia de los casos de prueba durante el desarrollo de la
aplicación, los casos de prueba garantizan en buena medida que la aplicación funciona
correctamente ante las situaciones contempladas.
Subdirección General de Desarrollo, Tecnología e Infraestructuras.
Página: 9
Descargar