Programación en castellano
Inicio > Tutoriales > Lenguajes orientados a objeto > J2EE > Construir Aplicaciones EJB con JBoss, Lomboz y Eclipse
-Tutoriales

Construir Aplicaciones EJB con JBoss, Lomboz y Eclipse


Crear un Bean de Sesión sin Estado

Esta página cubre cómo crear un componente EJB de sesión sin estado. Este bean será el responsable de autenficiar al usuario comunicándose con la base de datos utilizando un DAO (Data Access Objetc) que encapsula el código JDBC. Un DAO tiene todos los atributos (campos) y comportamientos (métodos) correspondientes al bean que lo está utilizando.

A todos los clientes, suministradores y managers de MyStore se les ha suministrado un nombre de usuario y un userid para acceder a los servicios de MyStore, pero para poder acceder a estos servicios todas estás entidades primero tienen que entrar (login) en el sistema (MyStore). El método de autentificación se llama loginUser, y toma dos parámetros String: username y password y devuelve el userID si la autenficación tuvo éxito.

Nota:
El método loginUser es un método de negocio, normalmente los métodos de negocio llevan a cabo operaciones o procesamientos de valores sobre componentes EJB. Desde la perpectiva de los clientes, ellos sólo pueden ver los métodos de negocio e invocarlos sobre un bean.

. Crear el Proyecto J2EE:

Bien, empezemos a escribir el primer componente de este tutorial:

  • Ve a File > New > LombozJ2EE Project, aparecerá el wizard de creacción de proyectos.
  • Pon MyStore como nombre del proyecto y pulsa Next .
  • Debajo de Java Settings Check source, debería estár MyStore/src, las librerías deberían apuntar a $JAVA_HOME, luego pulsa Next.
  • Nota:
    Este paso se vió en páginas anteriores, pero debido a un bug en Eclipse 2.1, es importante chequear que la configuración de las librerías es la adecuada.
  • Dentro de Create J2EE Module, selecciona la pestaña Web Modules y pulsa Add.., introduce OnlineStore como el nombre de módulo; y pulsa OK como se muestra en la siguiente figura:
  • Dentro de Create J2EE Module, selecciona la pestaña EJB Modules y pulsa Add.., introduce MyStoreMgr como el nombre el módulo y pulsa OK.
  • Dentro de Create J2EE Module, selecciona la pestaña Targeted Servers, selecciona JBOSS 3.2.1 ALL pulsa Add.. y luego Finish.

. Crear el Bean sin Estado:

  • Ve a Package Explorer, expande el nodo Mystore, selecciona src, pulsa el botón derecho y aparecerá un menú desplegable.
  • En el menú ve a New > Lomboz EJB Creation Wizard.
  • Introduce au.com.tusc.session, como el nombre del paquete, StoreAccess como nombre del bean y selecciona el tipo de bean como stateless; pulsa Finish.

Esto creará un paquete llamado au.com.tusc.session bajo src y también creará el bean StoreAccessBean dentro de ese paquete, como se ve en la siguiente figura:

Como podrás apreciar en la siguiente figura, se ha creado una etiqueta a nivel de clase (@ejb.bean), que tiene asignados el tipo del bean, su nombre y el nombre JNDI que se generará en el interface Home. Esta etiqueta también generará los descriptores de despliegue en los ficheros ejb-jar.xml y jboss.xml cuando generes tus clases EJB, lo que se cubrirá un poco más adelante.

Nota:
Esto generará el nombre del bean, el nombre JNDI, y el tipo del bean que hay en el fichero. También, se le añade Bean al nombre del fichero. De nuevo, hay que ser cuidadoso con las convenciones de nombrado, especificando sólo el nombre del bean en el wizard sin añadirle la palabra Bean ya que el wizard la añadirá por nosotros.
Si expandes el nodo MyStoreMgr/META-INF dentro del explorador de paquetes verás que Lomboz ha generado siete ficheros utilizando Xdoclet como se ve en la siguiente figura:

Ahora vamos a generar todos los interfaces, incluyendo el Home, el Remote, el DAO y otras clases de ayuda. Explicaremos porqué un poco más adelante, por el momento sólo sigue estos pasos. Pero antes de que te excites demasiado hay algunos conceptos que cubrir.

  • Ve a MyStoreMgr/META-INF y selecciona o abre el fichero ejbGenerate.xml.
    Nota:
    Lomboz utiliza este fichero para generar los interfaces y clases de ayuda necesarias, por eso, en el caso de que tengas necesidades especiales tendrás que personalizar este fichero. (Mira la documentación de Xdoclet para más información).
    El fichero ejbGenerate.xml se genera sólo una vez cuando creamos el módulo EJB. Por eso, cualquier cambio realizado en este fichero se reflejará incluso si modificamos nuestra clase bean y generamos las clases una y otra vez.

    Como puedes ver a partir del fragmento de código mostrado en la anterior figura, se han definido las siguientes etiquetas:

    • <dataobject/> genera objetos de datos para contener valores de campos persistentes del EJB, que corresponden con columnas en la tabla de la base de datos asociada
      Nota:
      <dataobject/> se ha quedado obsoleto en favor de Value Object que es más poderoso en términos de relaciones (1-1, 1-n y n-m).
    • <utilobject/> Crea un método para generación de GUID y para acceder a los objetos Home local y remoto.
    • <remoteinterface/> Genera los interfaces remotos para EJBs.
    • <localinterface/> Genera los interfaces locales para EJBs.
    • <homeinterface/> Genera los interfaces home remotos para EJBs.
    • <localhomeinterface/> Genera los interaces home locales para EJBs.
    • <entitypk/> Genera clases de claves primarias para EJBs de entidad.
    • <entitybmp/> Crea clases de bean de entidad para EJBs de entidad BMP.
    • <entitycmp/> Crea clases de bean de entidad para EJBs de entidad CMP.
    • <session/> Genera clases de bean de sesión.
    Nota:
    No hay una etiqueta para generar un DAO.
    Por eso, tenemos que incluir esta etiqueta <dao/>.
    Si quieres ver más detalles, visita la documentación de Xdoclet.

    Como puedes ver en este otro fragmento del código también se han definido las siguientes etiquetas:

    • <jboss/> es una etiqueta específica de JBOSS que éste necesita. Tienes que especificar datasource, datasourcemapping y preferredrelationmapping. Como difieren según las bases de datos, debes especificar los valores apropiados para tu entorno. Si comentamos estas etiquetas JBOSS utilizará los valores por defecto correctos para la base de datos interna Hypersonic SQL, pero por el momento los rellenaremos de cualquier forma.

    Los otros dos ficheros importantes para nosotros son ejb-jar.xml y jboss.xml. El primero tiene todos los descriptores de despliegue para los beans y el segundo tiene los descriptores de despliegue específicos de JBOSS requeridos por el propio JBOSS.

    Nota:
    El fichero ejb-jar.xml se genera cada vez que se generan las clases interfaces y de ayuda para nuestro bean. Para la primera vez, está vacío. jboss.xml también se generará cada vez que generemos las clases de nuestro bean.

. Configurar el DAO:

Ahora, personalicemos ejbGenerate.xml para configurar un DAO.

  • Hemos incluido una etiqueta <dao> que especifica el directorio de destino para el interface DAO generado y qué patrón utilizar:

  • Hemos incluido el datasource, el datasoucremapping y el preferredrelationmapping mostrados en el siguiente fragmento de código:
    1. datasource="java:/DefaultDS" es un nombre JNDI local para la fuente de datos a utilizar.
    2. datsourcemapping="Hypersonic SQL" mapea los objetos/valores a las columnas y los tipos de datos asociados con esas columnas.
    3. preferredrelationmapping="foreign-key" define el tipo de base de datos a utilizar.

    Como estámos utilizando la base de datos Hypersonic, estos parámetros son los apropiados. Estos parámetros están relacionado con el fichero de configuración standardjbosscmp-jdbc.xml que controla los mapeos CMP-a-JDBC para JBOSS. Este fichero reside en $JBOSS_HOME/server/conf/. Abajo puedes ver un fragmento del código de standardjbosscmp-jdbc.xml:

Nota:
La forma en que trabaja Xdoclet es un poco diferente de algunos estilos de programación convencionales, las etiquetas de Xdoclet generarán estos interfaces (home y remoto) junto con las clases de ayuda necesarias, que luego se utilizarán en las clases del bean y de la implementación de DAO. Sin embargo, hasta que no estén generadas, no podemos escribir ningún método de negocio en el Bean ni envolturas JDBC en la clase de implementación del DAO. Si esto te parece confuso simplemente sigue los pasos, espero que pronto se te aclare todo esto.

. Crear el Interface DAO:

Como vamos a utilizar un DAO para acceder a la base de datos para este Bean sin estado, tenemos que crear una clase DAOImpl que implemente el interface DAO generado.

  • Ve a src y añade un paquete llamado au.com.tusc.dao; añade una clase llamada StoreAccessDAOImpl en ese paquete:
  • Ahora ve a tu clase Bean y declara esta etiqueta a nivel de clase (es decir, en la parte superior) para generar el interface DAO:
    @ejb.dao class="au.com.tusc.session.StoreAccessDAO"
     impl-class="au.com.tusc.dao.StoreAccessDAOImpl"
    
  • Expande el nodo StoreAccessBean en el explorador de paquetes. Pulsa con el botón derecho y aparecerá un menú desplegable. En ese menú ve a Lomboz J2EE > Add EJB to module, selecciona EJB '[MyStoreMgr]' y pulsa OK.
  • Expande el nodo MyStoreMgr bajo MyStore Project en el explorador de paquetes. Pulsa con el botón derecho y aparecerá un menú desplegable. Ve a Lomboz J2EE > Generate EJB Classes como se muestra en la siguiente figura:

Los interfaces EJB y las clases de ayuda se generan en el directorio ejbsrc/au.com.tusc.session como se muestra en la siguiente figura:

Se han generado 7 ficheros:

  • StoreAccess es el interface remoto.
  • StoreAccessLocal es el interface local.
  • StoreAccessSession extiende nuestra clase bean llamada StoreAccesBean.
  • StoreAccessHome es el interface home remoto.
  • StoreAccessLocalHome es el interface home local.
  • StoreAccessUtil es una clase de ayuda que tiene métodos para acceder a los interfaces Home y LocalHome junto con la generación del GUID.
  • StoreAccesDAO es el interface DAO que se utilizará para implementar nuestro StoreAccessDAOImpl en au.com.tusc.dao.

StoreAccessDAO se genera mediante esta etiqueta declarada en StoreAccesBean. Si no declaras esta etiqueta en este fichero no se generará este interface:

@ejb.dao class=au.com.tusc.session.StoreAccessDAO
   impl-class=au.com.tusc.dao.StoreAccessDAOImpl

Otros ficheros de interés que se generan son ejb-jar.xml y jboss.xml en MyStoreMgr/META-INF.

Como se muestra en la siguiente figura, se han generado unos nuevos descriptores en el fichero ejb-jar.xml:

Estos descriptores se han generado mediante la siguiente etiqueta declarada en el fichero StoreAccesBean:

@ejb.bean name ="StoreAccess"
  jndi-name="StoreAccessBean"
  type="Stateless"

Esta etiqueta la añadió Lomboz en el wizard de creación del bean.

Esta etiqueta también genera los siguientes descriptores de despliegue en jboss.xml como se ve en el siguiente fragmento:

Entonces, ya sabes cuales son las clases responsables de generar las clases, los interfaces y los descriptores.

. Añadir un Método de Negocio:

El siguiente paso es añadir un método de negocio al bean.

  • Ve a StoreAccesBean pulsa con el botón derecho y selecciona New en el menú desplegable; selecciona Lomboz Ejb Method Wizard.
  • Añade un método de negocio con la siguiente firma:
     
    signature: public String loginUser (String username, String password).
    
  • Selecciona Method Type como Business e Interface como Remote como se ve en la siguiente figura:
  • Este wizard genera un método loginUser en nuestra clase bean, con la etiqueta a nivel de método @ejb.interface mostrada abajo:

    Esta etiqueta es la responsable de generar este método en el Interface Remoto (en este caso es StoreAccess que se creará una vez que generemos las clases. Esta etiqueta se cubrirá un poco más adelante.

    Ahora, este método de negocio necesita invocar a un método del DAO, através del que se comunicará con la base de datos. Por lo tanto, añadiremos otra etiqueta a este método, para que en el interface DAO se genere un método con esta firma, que podemos implementar en la clase DAOImpl. Entonces este método de negocio puede invocar el método de la clase DAOImpl para obtener el resultado deseado.

    @dao.call name="loginUser"

    Añade esta etiqueta como se ve en la siguiente figura:

    Ahora genera de nuevo tus clases EJB como viste en los pasos anteriores.

    Nota:
    Ok, OK!, como referencia aquí tienes los pasos que tienes que seguir:
    1. Expande el nodo MyStoreMgr en el proyecto MyStore en el Package Explorer.
    2. Pulsa con el botón derecho y aparecerá un menú desplegable.
    3. Ve a Lomboz J2EE > Generate EJB

    Después de generar las clases, primero veremos el interface DAO generado y luego la clase Sessión.

  • En StoreAcessDAO se han generado dos métodos:
    1. init() por defecto.
    2. loginUser(), generado por esta etiqueta:
      @dao.call name="loginUser"
    Nota:
    Por favor, no edites ninguna clase generada por Xdoclect.
  • En StoreAcessSession hay dos métodos de interes:
    1. getDAO() crea un ejemplar de la clase DAOImpl.
    2. loginUser(), llama al método loginUser de la clase DAOImpl, que tenemos que implementar.

    Fragmento de código de StoreAccessSession:

. Implementar el Interface DAO:

Ahora, implementaremos los métodos de la clase StoreAccessDAOImpl:

  • Primero importamos los siguientes paquetes:
    javax.naming.InitialContext;
    javax.sql.DataSource;
    java.sql.Connection;
    java.sql.PreparedStatement;
    java.sql.ResultSet;
    java.sql.SQLException;
    
  • Cambia la declaración de tu clase para que StoreAccessDAOImpl implemente StoreAccessDAO.
  • Añade un campo para almacenar la referencia a la factoría de recursos JDBC:
    private DataSource jdbcFactory;
  • En el método init(), busca la referencia jdbc/DefaultDS utilizando el aPI JNDI, y almacena la referencia en la variable jdbcFactory.
    El string de búsqueda es java:comp/env/jdbc/DefaultDS.
  • En el método loginUser(), primero obtenemos la conexión a la base de datos utilizando jdbcFactory.
  • Crea una sentencia SQL que busque el userid en la tabla StoreAccess donde userid y password se proporcionan para cada usuario.
  • Devuelve el userid si tiene éxito, si no lo tiene, lanza una SQLException.
  • Vuelve a tu método loginUser en la clase StoreAccessBean, y añade algunas sentencias de depuración como se muestra en este fragmento:
Nota:
No tenemos que llamar al método loginUser de StoreAccessDAOImpl, ya que está siendo invocado por el método loginUser de la clase StoreAccessSession que desciende de la clase StoreAccessBean, es decir, la clase StoreAccessSession ha sobreescrito este método.

Abajo puedes ver un fragmento de código de StoreAccessSession:

. Añadir Métodos de Retro-llamada:

Ahora, añadiremos los siguientes métodos de retrollamada a la clase StoreAccessBean:

  1. setSessionContext
  2. UnsetSessionContext
Nota:
Es el contenedor EJB el que invoca a estos métodos de retro-llamada.
  • Importa la clase SessionContext
    import javax.ejb.SessionContext;
  • Añade un campo para almacenar sessionContext:
    protected SessionContext ctx;
  • Añade un método setSessionContext con sessionContext como parámetro y asignále a éste la variable sessionContext como se muestra en el siguiente fragmento de código:
  • De forma similar añade el método unsetSessionContext, asigna un valor null a la variable, como has visto arriba.
  • Nota:
    La clase StoreAccessSession desciende de la clase abstracta StoreAccessBean e implementa SessionBean, que sobreescribirá todos los métodos del interface SessionBean. Por eso, después de finalizar estos métodos de la clase bean, genera de nuevo tus clases EJB. Se sobreescribirán los métodos de SessionContext, como se ve en el siguiente fragmento de código:

Ahora veamos los interfaces Home y Remote generados.

En el caso del interface Remote todos los métodos de negocio declarados en el bean se han generado con la misma firma. Esto es a cusa de las etiquetas a nivel de clases declaradas en el bean StoreAccess que hemos discutido antes. Abajo puedes ver un fragmento del código:

Por eso, loginUser se ha generado en un Interface Remote llamado StoreAccess como se ve abajo a causa de esta etiqueta:

En el caso del interface Home sólo se ha creado un método llamado create, que se genera por defecto a causa de la etiqueta <homeinterface/> que hay en ejbGenerate.xml como se ve abajo:

Además de esto, están JNDI_NAME y COMP_NAME (que es el nombre lógico para buscar el componente), estos se generan mediante la etiqueta declarada a nivel de clase en la clase StoreAccessBean, como se puede ver en la siguiente imagen:

Nota:
Para ver otras opciones asociadas con estas etiquetas no dudes en ojear la sección de ejbdoclet en la documentación de Xdoclet.

Ahora que ya hemos cubierto todos estos aspectos y la funcionalidad de nuestro bean está completa. Vamos a por los descriptores de despliegue...

. Desplegar el Bean:

Para poder desplegar el bean hemos declarado unas cuantas etiquetas en la clase StoreAccessBean, como puedes ver en el siguiente código:

  • Añade esta etiqueta a nivel de clase (en la parte superior):
    @ejb.resource-ref res-ref-name="jdbc/DefaultDS"
    res-type="javax.sql.Datasource"
    res-auth="Container"
    

    Esta etiqueta generará los descritores de despliegue en ejb-jar.xml, ya que el bean tiene que saber a qué datasource te vas a conectar, de qué tipo es, etc. Esto generará estos descriptores como se muestra en el siguiente fragmento de código:

  • Añade esta etiqueta en StoreAccessBean a nivel de clase (en la parte superior):
    @jboss.resource-ref res-ref-name="jdbc/DefaultDS" jndi-name="java:/DefaultDS"
    

    Esta etiqueta generará los descriptores de despliegue en jboss.xml, ya que el servidor de aplicaciones tiene que conocer el nombre JNDI del datasource con el que se tiene que registrar. Esto generará los descriptores mostrados en el siguiente código:

Ahora que todo está completo, es hora de desplegar el bean.

  • Primero, regenera tus clases EJB siguiendo los pasos que hemos visto antes.
    Nota:
    Hemos generado las clases una y otra vez, para poder explicar cada paso y sus resultados. Una vez que estés familiarizado con estos pasos dejarás de necesitar estas iteracciones. De cualquier forma, no tiene importancia, ya que tu implementación nunca se verá modificada por este paso extra.
  • Ve a Lomboz J2EE View y expande el nodo MyStore , expande MyStoreMgr y selecciona Jboss 3.2.1 ALL.
  • Pulsa con el botón derecho y selecciona Debug Sever en el menú desplegable, como se ve en la siguiente figura:
  • Ve al nodo MyStoreMgr en la vista LombozJ2EE, pulsa con el botón derecho y selecciona Deploy en el menú desplegable:
  • Y ahora espera el resultado del despliegue. Si todo ha ido bien, verás en la consola un mensaje como éste:

Ahora, ya hemos desplegado nuestro bean, sólo nos queda crear un test de cliente que invoque el método loginUser sobre StoreAccessBean...

. Crear Nuestro Test de Cliente:

  • Ve al nodo Project MytStore, selecciona el nodo src y pulsa con el boton derecho.
  • Selecciona New en el menú desplegable; selecciona Lomboz EJB Test Client Wizard como se ve en la siguiente figura:
  • Seleciona au.com.tusc.client como el nombre del paquete, SessionClient como el nombre, au.com.tusc.session.StoreAccessHome como el EJB Home y au.com.tusc.session.StoreAccess como el EJB Interface, como se ve en la siguiente figura:

    Esto generará los métodos necesarios en nuestra clase SessionClient y sólo tendremos que invocar al método loginUser en el bean, como se ve abajo:

  • El último paso es escribir el código de nuestro cliente:

    Añade estas líneas dentro del método testBean, como se ve en la siguiente figura:

    System.out.println("Request from client : ");
    System.out.println("Reply from Server: Your userid is "+
    myBean.loginUser("ANDY","PASSWD"));
    

. Probar Nuestro Cliente:

  • Ahora, para poder probar el cliente, selecciona el nodo SessionClient, vea al menú superior y selecciona el icono con el "hombre corriendo".
  • Selecciona Run as y selecciona Java Application, como se ve en la siguiente figura:
  • Ahora en tu consola, si obtienes una respuesta U2 para ANDY, quiere decir que tu llamada ha tenido éxito, como puedes ver en la siguiente imagen:
Nota:
Ahora ya has desplegado tu primer bean de sesión sin estado y lo has probado con éxito; a partir de ahora deberías sentirte cómodo utilizando Lomboz. En el futuro no entraremos en los detalles de los pasos para utilizar Lomboz y nos concentraremos en otros aspectos de los beans.
 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad
Mantenida por: Claudio y Dani.

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: jugar gratis | amor | navidad 2009 | registro de dominios | servidores dedicados
más internet: comprar | gratis | posicionamiento en buscadores | decoración libre | gifs animados