Desarrollo Rápido de Aplicaciones J2EE con Oracle ADF y MySQL en jDeveloper

Puede encontrar la versión original de este artículo en Inglés en:

www.developer.com/

Introducción

Este artículo demuestra cómo se puede utilizar ADF para diseñar una aplicación Web. Usará el IDE JDeveloper 10g de Oracle. Puede descargar una versión gratuita desde aquí. También utilizará la popular base de datos open-source MySQL, que también puede descargar desde aquí. Si usted prefiere utilizar la base datos de Oracle, los ajustes necesarios le deberían resultar triviales.

ADF

En un esfuerzo por mantener las cosas sencillas, hemos querido evitar una explicación detallada de ADF. Puede encontrar demos y artículos en la site de JDeveloper. Sin embargo si que veremos una explicación de alto nivel de los componentes ADF, y cómo se pueden conjuntar en la arquitectura MVC.

Modelo

Entidades

Un objeto entidad (Entity) de ADF representa una entidad de negocio. Esto normalmente se traduce en una fila de datos de una tabla, y cada atributo de la entidad representa una columna de esa tabla.

En ADF, la entidad maneja otras tareas, como las validaciones de negocio y las máscaras de formato. En la mayoría de los casos, el modelo es el lugar más lógico para dirigir esos conceptos porque permitirá una máxima reutilización. Las validaciones, predicadas por requerimientos de negocio, se supone que son importantes sin importar como se utilice el modelo. Por ejemplo, la verificación de que un empleado siempre está asignado a un y sólo un departamento no cambiará si la aplicación se convierte desde una aplicación Web a una aplicación Swing. ADF propagará esas validaciones y formatos al controlador y a la vista, aliviando la necesidad de corregir esos problemas en otros lugares.

Vistas

Un objeto vista de ADF expone un objeto entidad a los usuarios de la aplicación. Se puede acceder a una entidad desde varios sitios, pero el contexto en el que se utiliza variará. Se pueden establecer filtrados, ordenaciones y relaciones entre objetos mediante un objeto vista, asegurando que el modelo se representa en la forma en la que tiene más sentido.

Módulo de aplicación

El módulo de aplicación ADF empaqueta varios componentes vista mientras proporciona acceso a su capa de servicios de negocio, que podría utrilizar tecnologías como EJB para manejar su base de datos. El módulo de aplicación proporciona vistas ADF con soporte de transaciones, y otros servicios importantes centrados en los datos.

Vista y Controlador

Nada en su modelo debería dictar una tecnología de vista particular. Un módulo de aplicación puede servir como base para una aplicación Swing o para una aplicación Web basada en Struts. Si desarrolla una aplicación ligera, los componentes Swing se podrían comunicar directamente con el módulo de aplicación. Cuando desarrolle una aplicación basada en la Web, su aplicación usará un controlador claramente definido para manejar la interacción entre el modelo y la vista.

Controlador

En versiones anteriores, ADF proporcionaba su propio controlador. Ese controlador ha sido reemplazado en favor de Struts. Struts utiliza un fichero XML, llamado struts-config.xml, para manejar las peticiones de la aplicación y despacharlas a los manejadores adecuados. Los desarrolladores con experiencia en Struts apreciarán la posibilidad de utilizar esos conocimientos.

Vista

JDeveloper hace sencillo diseñar páginas visualmente utilizando JSP y JSTL. ADF también proporciona su propio marco de trabajo para vistas, llamado UIX, que ofrece un conjunto de elementos HTML para generar rápidamente páginas de aspecto consistente. Los componentes UIX se convertirán en la base de la implementación de JSF (JavaServer Faces) en futuras versiones.

Construir una Aplicación de Ejemplo

La aplicación que construiremos permite a los empleados reservar salas de conferencia para reuniones de trabajo. Como hemos mencionado anteriormente, se utiliza una base de datos MySQL para crear dos tablas: conference_rooms y room_reservations. Abajo puede ver el DDL para crear estas tablas:

DROP TABLE IF EXISTS conference_rooms;

CREATE TABLE conference_rooms
(
room_id           INTEGER NOT NULL AUTO_INCREMENT,
room_name         VARCHAR(32),
number_of_seats   INTEGER,
PRIMARY KEY (room_id)
);

DROP TABLE IF EXISTS room_reservations;

CREATE TABLE room_reservations
(
reservation_id    INTEGER NOT NULL AUTO_INCREMENT,
room_id           INTEGER NOT NULL,
reservation_start DATETIME,
reservation_end   DATETIME,
reservation_team  VARCHAR(50),
PRIMARY KEY (reservation_id)
);
	

Arranque JDeveloper si no lo ha hecho ya. En la parte izquierda, verá el Applications-Navigator. Pulse sobre la pestaña Connections para establecer una conexión con su base datos MySQL. Sin embargo, antes de hacer esto, es necesario poner a disposición de JDeveloper y del servidor OC4J embebido el driver JDBC de MySQL. Puede hacer esto copiando el fichero .jar del driver al directorio j2eehomeapplib del directorio raíz de JDeveloper (por ejemplo: /opt/jdev/j2ee/home/applib). Una vez completado, realice los siguientes pasos en el Applications-Navigator:

  • Seleccione Database. Pulse con el botón derecho y elija New Database Connection... Pulse sobre Next.
  • Introduzca 'MySQL' para el Connection Name y seleccione 'Third Party JDBC Driver' para el Connection Type. Pulse sobre Next.
  • Aparecerá la página de autentificación. Introduzca el nombre de usuario y la password para su base de datos MySQL. Marque el checkbox Deploy Password, y pulse sobre Next.
  • Luego, seleccione la Driver Class como com.mysql.jdbc.Driver e introduzca la URL de la base de datos como jdbc:mysql://localhost/{database name}. Pulse sobre Next.
  • Pulse sobre el botón Test Connection. Si se puede conectar verá la palabra Success. Pulse sobre el botón Finish.

Construir un Modelo

Para crear una aplicación en JDeveloper, pulse con el botón derecho sobre la pestaña Applications en el Applications-Navigator. Seleccione New Application Workspace, y luego teclee RoomReservations como el Application Name. Deje la Application Template como Web Application [Default].

Estas acciones crearán una nueva aplicación basada en una plantilla que contiene dos carpetas: Model y ViewController. Como sugieren sus nombres, contendrán el modelo de su aplicación MVC y el controlador Struts y las páginas de presentación respectivamente.

Primero, necesita crear dos objetos Entity de ADF, basados en su tablas de MySQL.

  • Pulse con el botón derecho sobre la carpeta Model, y seleccione New.
  • Bajo la categoría Business Tier, seleccione Business Components.
  • De la lista de ítems, seleccione Entity Object y pulse OK.

La siguiente pantalla del asistente le pide que establezca una conexión con la base de datos para obtener los objetos del esquema.

  • La primera página debería pedirle que conecte con su fuente de datos MySQL y pulse sobre Connect.
  • Continúe en la ventana Create Entity Object. En Database Objects, seleccione la tabla: conference_rooms.
  • Pulse varias veces sobre el botón Next hasta que llegue a la pantalla Attribute Settings. Debería seleccionar el atributo RoomId. El asistente de ADF debe conocer el identificador del objeto. Marque el box Primary Key y pulse Next.
  • Continúe con el asistente hasta el final.

Usted ha creado un objeto Entity llamado ConferenceRooms. Ahora necesita un segundo objeto que represente la tabla room_reservations. Utilizando los pasos anteriores como guía, cree el modelo RoomReservations. Cuando llegue a la pantalla Attribute Settings, marque reservationId como la clave primaria.

Ahora que tiene las entidades, necesita objetos vista para exponerlas al resto de la aplicación. Como recordará, una View ADF expone objetos Entity al resto de la aplicación. Una única entidad ADF podría requerir varios objetos vista en aplicaciones más complicadas.

  • Para crear un objeto Vista para ConferenceRooms, pulse de nuevo sobre Model y seleccione New.
  • Bajo la categoría Business Tier, seleccione Business Components.
  • Esta vez, de la lista de ítems seleccione View Object. Pulse OK y luego Next.
  • En la ventana Create View Object, llame a esta vista como ConferenceRoomsView. Pulse sobre Next.
  • La siguiente página del asistente le pedirá que elija una entidad para la vista, seleccione ConferenceRooms y pulse Next.
  • En la siguiente patalla seleccione todos los atributos disponibles para esta vista ADF
  • Pulse sobre Next y continúe hasta encontrar el botón Finish.

Repita los pasos anteriores para crear RoomReservationsView partiendo de su otra Entidad ADF relevante, RoomReservations. Sin embargo, esta vez, deténgase cuando el asistente muestre la vista SQL generada por el marco de trabajo ADF.

  • En la sección Query Clauses, pulse sobre Edit... para editar el campo Order By de la vista
  • Seleccione RoomReservations.reservation_start en la lista para ordenar los contenidos según la fecha de inicio.
  • Como usted ha alterado la vista, se le pedirá que compruebe la query para asegurar su correción.
  • Pulse sobre Next y proceda hasta llegar a Finish.

Usted querrá presentar a los usuarios una vista detallada de las salas y las reservas actuales. Herramientas como Oracle Forms proporcionan soporte interno para dichas características. Sin embargo, el soporte de formularios de detalles ha faltado en los marcos de trabajo de desarrollo Web. Afortunadamente, el marco de trabajo ADF lo hace sencillo. Siguiendo estos pasos, usted establecerá un enlace entre sus vistas para permitir que ADF coordine las actividades entre ellas.

  • Pulse con el botón derecho sobre Model y seleccione New.
  • Elija View Link entre los Business Components disponibles. Pulse sobre Next, y de nuevo sobre Next.
  • Llame a su vista RoomReservationsViewLink y pulse sobre Next.
  • En el panel izquierdo, expanda ConferenceRoomsView y seleccione el atributo RoomId.
  • En el panel derecho, seleccione RoomId en RoomReservationsView y pulse sobre Add.
  • Pulse sobre Next para ver la join SQL generada como resultado. Sigua hasta alcanzar el botón Finish.

Falta una pieza en su modelo de aplicación: un Application Module para unir la 'M' de su aplicación MVC a la capa de servicios de negocio.

  • En el Application Navigator, bajo Model, Application Sources, pulse con el botón derecho sobre el paquete del modelo y seleccione New Application Module. Pulse sobre Next.
  • Llame a su Módulo de Aplicación RoomReservationsAppModule y pulse sobre Next.
  • La siguiente ventana le pedira las vistas relevantes para el RoomReservationsAppModule. En el panel izquierdo, seleccione los tres componentes ADF View: ConferenceRoomsView, RoomReservationsViewLink y RoomReservationsView. Estas acciones crearán ejemplares de cada un de las vistas en el Módulo de Aplicación.
  • Continúe hasta alcanzar el botón Finish.


Modelo en el Navegador de Aplicaciones de JDeveloper

Vista/Controlador

En este punto, usted no se ha comprometido con ninguna tecnología de vista particular. RoomReservationsAppModule podría servir fácilmente como la base para una aplicación Swing. En vez de eso, usted creará una aplicación basada en Web. ADF utiliza el marco de trabajo Struts para implementar el controlador de la aplicación. Al igual que con la vista, aquí tampoco está limitado. Sin embargo JDeveloper proporciona varias características para editar visualmente páginas JSP o páginas UIX. Aquí utilizaremos la tecnología UIX.

Lo primero que hay que hacer es crear una página y especificarla en struts-config.xml.

  • En el Application Navigator, bajo ViewController, Web Content, haga doble click sobre struts-config.xml.
  • En la Component Palette de la derecha, seleccione Data Page y arrástrela a su editor vacío de Struts Data Flow Editor.
  • Renombre este nuevo objeto como /main; luego, haga doble click sobre él.
  • De la lista de opciones, seleccione /main.uix como el nombre de página para designar que es un componente UIX y pulse sobre OK.
  • Debería aparecer el Data Control Palette a la derecha, reemplazando a la Component Palette. (si no es así, teclee Ctrl+Shift+d para seleccionarla.)
  • Expanda el árbol que aparece para ver los ejemplares de Vistas que asignó a su módulo de aplicación.
  • Expanda el nodo ConferenceRoomsView1. Seleccione RoomReservationsView1 dentro de él.
  • En la caja Drag and Drop As:, seleccione Master Detail (One to Many).
  • Arrastre el RoomReservationsView1 seleccionado dentro de la caja punteada del editor que muestra main.uix.

Con unos pocos clicks de ratón, ha creado un sencilla página de detalles. Observe que se han añadido automáticamente los botones de navegación y paginación. Posteriormente podrá personalizar su vista, modificando etiquetas, añadiendo aspecto y comportamiento, etc. Por defecto, ADF aplica el 'BLAF' (browser look and feel). Puede cambiar el aspecto y comportamiento editando el fichero uix-config.xml. Sin embargo, no iremos más allá para corregir estos problema. Sólo haremos algunos cambios cosméticos y luego ejecutaremos la aplicación.

  • Seleccione el bloque maestro en main.uix. Junto al Data Control Palette, debería ver la ventana Property Inspector.
  • Cambie el text de Master a Conference Rooms.
  • Cambie el text del bloque Detail a Current Room Reservations.
  • Pulse en la pestaña Components para mostrar la Component Palette. Se deberían mostrar todos los componentes UIX con una colección de artilugios HTML para añadir a su página UIX. Seleccione image y arrástrelo sobre el bloque maestro.
  • Seleccione cualquier gráfico compatible con la Web que tenga en su sistema y añádalo como el logo de su página. Yo he añadido un logo muy sencillo.
  • JDeveloper le preguntará si quiere añadir la imagen a la raíz de su aplicación. Hágalo.

Puede ejecutar la aplicación en el servidor OC4J interno proporcionado con JDeveloper pulsando con el botón derecho sobre /main en el Struts Data Flow Editor y seleccionado Run. No son las páginas más bonitas del mundo, y hay algunos ítems superfluos, pero estos son problemas menores que se pueden corregir con posterioridad.

Hacer nuevas Reservas

La página actual muestra las reservas actuales en un formato tabular. Ahora, creará una página para hacer nuevas reservas:

  • De la Component Palette, arrastre una segunda Data Page al Struts Data Flow Editor.
  • Llame a este componente /newReservations.
  • Haga doble click y seleccione el valor /newReservations.uix. Pulse OK.
  • En la Data Control Palette, seleccione el ejemplar RoomReservationsView2 (el que no está junto a ConferenceRoomsView1).
  • Seleccione Input Form y arrástrelo dentro de la página para crear una página de entrada.
  • Como ReservationId se genera automáticamente, elimine esta unión seleccionandolo en el editor y pulsado delete.

UIX date controla por usted donde se añadieron los campos ReservationStart y ReservationEnd. Ahora, añadamos alguna lógica Struts.

  • En el grupo Struts Page Flow de la Component Palette, seleccione Action.
  • Arrastre la Action al diagrama de flujo para crear una nueva acción de Struts
  • Llame a esta acción NewReservationAction, y haga doble click sobre ella para crear su fichero fuente.
  • Cierre el editor de código que aparece conteniendo la nueva acción Struts.
  • Seleccione Page Link en la Component Palette.
  • Pulse /main en el diagrama y luego la acción NewReservationAction para crear un enlace.
  • Seleccione Forward en la Component Palette.
  • Pulse sobre la acción NewReservationAction en el diagrama y luego sobre /newReservations para craear un Forward de Strusts desde esta acción al formulario.
  • En el editor, seleccione el Forward llamado success y cambiélo por create.

Acaba de crear algunos mapeos Struts entre dos páginas de su aplicación. Todavía no ha introducido ningún código personalizado a su Action Struts. Si retorna al editor de main.uix verá un nuevo botón que ha generado el marco de trabajo como resultado de los mapeos que ha creado.

  • En el Property Inspector, cambie el texto del botón text a Add New Reservation...

Basándose en su trabajo hasta ahora, re-ejecutar la aplicación debería producir una página como la mostrada abajo. Pruebe a pulsar sobre el botón Add New Reservation.... Debería aparecer una página donde poder introducir una nueva reserva.


Página inicial de sus aplicación

En la página principal, observe una columna encabezada por Select. ADF proporciona una bonita forma de seleccionar un registro y pasar su identificador único junto con la petición. Normalmente usará esto para dar contexto a un petición de edición o borrado de una entrada particular. Esta demostración sólo cubrirá la creación de nuevas reservas, puede borrar este campo si lo desea.

Su aplicación se utiliza para reservar salas de conferencias. Normalmente, las reservas podrían durar una hora o dos, pero no todo el día. Sin embargo, viendo los datos parece que tiene un gran problema: por defecto la máscara de formato para las horas de inicio y final no muestran horas. Además, ahora que los usuarios pueden hacer reservas, tiene que corregir el problema de la validación. Debe asegurarse de que los usuarios:

  1. Sólo hacen reservas para fechas futuras.
  2. Introducen una hora de fin posterior a la hora de inicio.

Como se mencionó anteriormente, el marco de trabajo ADF le permite especificar este tipo de información en sus objetos Entity. Para hacer esto, necesita modificar el modelo de su aplicación, y esto tiene su sentido en este caso. Es como si usted quisiera que siempre se muestre la hora y definitivamente quiera que se fuercen esas validaciones. Ahora, volvamos al modelo para corregir los problemas de formateo y validación como acabamos de describir.

  • En el Applications - Navigator, pulse con el botón derecho sobre la entidad RoomReservations para abrirla y editarla.
  • Expanda Attributes; seleccione ReservationStart.
  • Seleccione la pestaña Control Hints.
  • Seleccione Format Type como Simple Date.
  • Seleccione Format como MM/dd/yyyy HH:mm.

Añada un formato idéntico para ReservationEnd. Luego, añada la lógica de validación:

  • Con RoomReservations todavía abierto, seleccione Validation.
  • Seleccione ReservationStart y pulse sobre New....
  • Está creado un CompareValidator, por eso deje las Rules como están.
  • Seleccione GreaterThan en Operator.
  • Seleccione Query Result en Compare With.
  • Seleccione la fecha actual del sistema utilizando la síntaxis de MySQL introducciendo SELECT NOW(); en el campo Enter SQL statement.
  • Error Message debería contener el texto: Start time must be greater than the current time!

Ya se ha asegurado de que las reservas sólo se podrán hacer para fechas futuras. Sigua estos pasos para asegurarse de que cualquier hora de fin especificada es posterior a la hora de inicio:

  • Seleccione Validation.
  • Seleccione ReservationEnd y pulse sobre New....
  • Deje Rules y Operator como están (CompareValidator y GreaterThan).
  • En vez de Query Operator, seleccione View Object Attribute en Compare With.
  • Bajo Select Attribute, seleccione ReservationStart en RoomReservationsView.
  • Error Message debería contener el texto: End time must be greater than the start time!

Cuando creó un enlace a su Action de Struts, creó un botón en la página maestra que le trajerá aquí. Normalmente es una buena idea canalizar todas las peticiones a través del controlador Struts. Sin embargo, si simplemente quiere crear un botón de navegación, puede hacerlo de esta forma fácilmente. Si necesita algún tipo de navegación desde su formulario de entrada hacia la página principal, lo puede añadir de esta forma:

  • Pulse en la pestaña Components para mostrar la Component Palette. Vaya a la sección All UIX Components.
  • Seleccione Button y arrástrelo al editor de la página newReservations.uix.
  • Modifique la etiqueta como 'View All Reservations en el Property Inspector.
  • En la propiedad destination, seleccione main.do de la lista desplegable para crear un link de vuelta a la primera página.

Después de aplicar estos cambios, ejecute la aplicación, e intente crear algunas reservas. Seleccione fechas y horas que violen las reglas de validación. En la siguiente imagen puede ver un intento de seleccioner una hora de fin anterior a la hora de inicio que resulta en un mensaje de error:


Error de Validación mientras se hace una reserva.

Conclusión

Entonces, ¿Qué ha conseguido? Ha creado una aplicación J2EE basada en MVC, en muy poco tiempo, sin escribir una sóla línea de código Java. Utilizando una base de datos MySQL, el marco de trabjo ADF le ha permitido crear un sistema de reservas totalmente funcional que se ha desplegado en el servidor OC4J de Oracle. Como nota final, las aplicaciones desarrolladas por ADF no están confinadas al servidor de aplicaciones de Oracle. JDeveloper proporciona soporte para instalar las librerías ADF y para empaquetar y desplegar una completa aplicación ADF en otro servidor de aplicaciones como JBoss.

Oracle ADF proporciona un entorno RAD (Rapid Application Development) para desarrollar aplicaciones J2EE de una forma rápida y eficiente.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE ARTÍCULO