07 noviembre, 2006

Análisis de una Aplicación J2ee (Frontend)

En este documento desarrollaremos un cliente web para la aplicación de empleados y departamentos. Se asume el que lector tiene los conocimientos básicos de Struts y de aplicaciones web J2ee (webapps).


Struts

Analicemos el siguiente diagrama de flujo de información de Struts.


El diagrama anterior debe leerse de la siguiente manera:

1 - identificacion.jsp - El usuario ingresa su empno y ename en esta página JSP. El formulario envia esa información al servlet identificarEmpleado.do. Este, invocando el método identificarEmpleado(empno,ename) del Facade (ya veremos como hacer para acceder a la fachada) obtiene el EmpDTO correspondiente (en función de los datos ingresados) y lo envia (seteado como atributo en el request) a la siguiente página JSP: datosEmpleado.jsp

2 - datosEmpleado.jsp - Esta página recibe como atributo en el request la instancia de EmpDTO con toda la información que necesitamos mostrar. Simplemente debemos preparar un link que apunte al servlet obtenerDepartamento.do y pasarle el deptno como parámetro en el URL. Algo así:



El servlet obtenerDepartamento.do accede al facade para invocar los métodos buscarDepartamento(deptno) y obtenerEmpleados(deptno). Los resultados los setea como atributos en el request y forwardea a la próxima página: datosDepartamento.jsp.

3 – datosDepartamento.jsp
Recibe como atributo en el request un DeptDTO y una colección de EmpDTO (que fueron seteados en el servlet anterior). Muestra los datos del departamento y la lista de empleados que allí trabajan. Arma un link para acceder a la página datosLocalidad.jsp (pasando como parámetro loc) y luego, por cada empleado, arma un link para volver a la página de datos del empleado. Obviamente este link no apuntará directamente a la página. Debe apuntar al servlet anterior (identificarEmpleado.do) quien (si corresponde) forwardeará a la página con la información completa del empleado.



Analicemos la vista gráfica del struts-config.xml (generada con MyEclipse)



Model View Controller

El siguiente diagrama muestra el flujo de información entre los componentes del MVC (Model View Controller)


View
El usuario ingresa su información en la página identificacion.jsp. Esta página tiene un formulario con action=“identificarEmpleado.do” y submitea la información al servlet IdentificarEmpleadoAction.java

Controller
El servlet (controller) accede al facade (model) para invocarle el método identificarEmpleado(enpno,ename). Obtiene el resultado (un EmpDTO o null) y forwardea el control a la siguiente página según el resultado obtenido.

Model
El model está representado por el facade pero recordemos que detrás de él se encuentran los objetos de negocio (Emp y Dept) y (por último) la base de datos con las tablas EMP, DEPT y sus relaciones.


Acceder al Facade desde los Servlets (.do)

Analicemos el código de identificarEmpleado.do (IdentificarEmpleadoAction.java)



Como vemos podemos acceder directamente a la fábrica de facade para obtener “la instancia” del facade. Recordemos que en FacadeFactory estamos utilizando un síngleton ya que una única instancia del facade nos alcanza para atender a todos los clientes.

Si fuera el caso que se necesite una instancia diferente de facade para cada cliente entonces deberíamos eliminar el síngleton y publicar instancias del facade en un listener de sesión. Así, cada usuario (accediendo a la sesión web) podría disponer de su propia instancia del facade.


La Conexión con la Base de Datos

En el código anterior estamos tomando la conexión como un atributo publicado en el ServletContext. Esta solución supone una única conexión con la base de datos que será compartida entre todos los usuarios durante toda la aplicación.

Para publicar la conexión como atributo en el servlet context utilizamos un ServletContextListener. La clase EscuchaContexto.java implementa esta interface, instancia y publica la conexión en el contexto de la aplicación web.



La solución anterior es suficiente para nuestra aplicación porque solamente realiza consultas. Pero si hubiera algún caso que implique manejar transacciones la solución ya no sería correcta y deberíamos definir un pool de conexiones en el container para tomar las conexiones desde allí.

Igualmente recordemos que si vamos a trabajar con la implementación EJB del facade no será nuestra responsabilidad instanciar las conexiones a la base de datos dado que la misma implementación de facade las gestionaba a través del pool de conexiones del EJB Container.