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 con Estado

Esta página cubre cómo crear un componente EJB con estado. Al contrario que los beans sin estado, los ejemplares de beans con estado están asociados con una sesión de cliente particular y por lo tanto pueden mantener información útil durante el tiempo de vida de esa sesión. Un ejemplo clasico y familiar dentro del contexto del comercio electrónico es una carrito de la compra.

Probaremos algo un poco menos ambicioso para empezar! Este bean es similar al StoreAccess creado en la página anterior excepto en que almacenará el userID del cliente, después de haber pasado la autentificacion.

Nota:
Este bean no se utilizará más a lo largo del tutorial, y este capítulo demuestra lo útiles que son los beans con estado.

. Crear un Bean sin Estado:

  • Ve al explorador de paquetes, expande el nodo del proyecto Mystore, selecciona src, pulsa con el botón derecho y aparecerá un menú.
  • En el menú selecciona New > Lomboz EJB Creation Wizard.
  • Introduce au.com.tusc.sessionState como el nombre del paquete, StoreAccessState como el nombre del bean y pulsa sobre Finish.

Esto creará un paquete llamado au.com.tusc.sessionState bajo src y dentro de ese paquete creará StoreAccessStateBean:

Como puedes ver en la figura anterior, se ha creado una etiqueta @ejb.bean a nivel de clase a la que se le ha asignado el tipo del bean, el nombre y el nombre JNDI que se generarán en el interface Home. Esta etiqueta también generará los descriptores de despliegue en los ficheros ejb-jar.xml y jboss.xml una vez generadas las clases EJB, lo que veremos un poco más adelante.

Nota:
Esto generará el nombre del bean, el nombre JNDI y el tipo del bean en el fichero. Además, al nombre del fichero se le añadirá la palabra 'Bean' ya que sólo le hemos dado el nombre StoreAccess. Debes ser cuidadoso con las convenciones de nombrado, sólo tienes que especificar el nombre del bean en el wizard (es decir, sin la palabra 'Bean' ya que él la añadirá por ti).

. Crear el Interface DAO:

Como vamos a utilizar un DAO para acceder a la base de datos para este Bean con Estado, utilizaremos la clase StoreAccesDAOImpl que implementamos en el capítulo anterior. Esto proporcionará la implementación para el interface DAO generado.

  • 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.sessionState.StoreAccessStateDAO"
        impl-class="au.com.tusc.dao.StoreAccessDAOImpl"
    
  • Expande el nodo StoreAccessStateBean en el explorador de paquetes.
  • Pulsa con el botón derecho y en el ménu que aparece selecciona Lomboz J2EE > Add EJB to module.
  • Selecciona EJB MyStoreMgr y pulsa OK:
  • Expande el nodo MyStoreMgr del proyecto MyStore en el explorador de paquetes.
  • Pulsa con el botón derecho y en el menú que aparece selecciona Go to Lomboz J2EE > Generate EJB Classes:

Bajo el directorio ejbsrc se generan los interfaces EJB y las clases de ayuda. Se han generado un total de siete ficheros:

  • StoreAccessState es el interface remoto.
  • StoreAccessLocal es el interface local.
  • StoreAccessStateSession extiende la clase bean llamada StoreAccesStateBean.
  • StoreAccessStateHome es el interface home remoto.
  • StoreAcessStateLocalHome es el interface home local.
  • StoreAccessStateUtil es una clase de ayuda que tiene métodos para acceder a los interfaces home y remoto además de generar el GUID.
  • StoreAccesStateDAO es el interface DAO, que implementa la clase StoreAccessDAOImpl bajo au.com.tusc.dao.

StoreAccessStateDAO se genera mediante la etiqueta declarada en StoreAccesStateBean como se muestra abajo. Si no declaras esta etiqueta en ese fichero no se generará este interface.

@ejb.dao class=au.com.tusc.sessionState.StoreAccessStateDAO
    impl-class=au.com.tusc.dao.StoreAccessDAOImpl

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

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

Estos descriptores se han generado mediante la siguiente etiqueta declarada en el fichero StoreAccessBean, que generó Lomboz:

@ejb.bean name =StoreAccessSate
jndi-name=StoreAccessStateBean
type=Stateful

Esta etiqueta también genera los siguientes descriptores en jboss.xml:

. Añadir un Método de Negocio:

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

  • Ve al nodo StoreAccesStateBean pulsa con el botón derecho y selecciona New en el menú que aparece.
  • Selecciona Lomboz EJB Method Wizard.
  • Añade un método de negocio con la siguiente firma:
    public String loginUser (String username, String password).
  • Selecciona el tipo de métoco como Business y el interface como Remote:

Este wizard genera un método loginUser en la clase bean, con la siguiente etiqueta a nivel de método:

Esta etiqueta es la responsable de generar este método en el interface remoto (en este caso es StoreAccessSate que se creará cuando generemos las clases).

Ahora, este método de negocio necesita invocar a un método del DAO, que encapsula el acceso a la base de datos.

Añade otra etiqueta a este método para que se genere un método con esta firma en el interface DAO. Podemos implementar este método en la clase DAOImpl para que el método de negocio pueda obtener el resultado deseado:

@dao.call name=loginUser

Añade esta etiqueta a nivel de método como se ve abajo:

Ahora genera de nuevo las clases EJB como se vió en pasos anteriores.

OK, OK!, Como referencia aquí tienes los pasos a seguir:
  • Expande el nodo MyStoreMgr del proyecto MyStore en el Explorador de Paquetes.
  • Pulsa con el botón derecho y en el menú desplegable selecciona Lomboz J2EE > Generate EJB Classes.

. Añadir Métodos de Retrollamada:

Al contrario que en el bean sin estado, el método ejbCreate tendrá un argumento. Este se utilizará para inicializar un campo persistente en el bean.

  • Añade este campo, y los métodos accesores y mutadores para acceder a él:
       private String userID;   
       
       /**
        * @ejb.interface-method 
        *  view-type="remote"
        */
       public void setUserID(String userID) {
          this.userID = userID;
       }
       
       /**
        * @ejb.interface-method 
        * view-type="remote"
        */
       public String getUserID() {
          return userID;
       }
    
  • Ahora añade el método ejbCreate con la firma:
    public void ejbCreate (String userID)
  • Asigna el userID al campo persistente userID que hemos creado arriba:

Ahora, los otros dos métodos de retrollamadas necesarios para completar este bean son:

  1. setSessionContext
  2. unsetSessionContext.

  • Añade un campo para contener sessionContext:
    protected SessionContext ctx;
  • Añade un método setSessionContext con sessionContext como parámetro y asignalo a la variable sessionContext:
  • De forma similar, añade un método unsetSessionContext que ponga a null la variable de contexto.
    NOTA:
    La clase StoreAccessStateSession desciende de la clase abstracta StoreAccessStateBean e implementa SessionBean, que sobrescribirá todos los métodos del interface SessionBean. Por eso, después de completar los métodos de la clase Bean debes regenerar las clases EJB. Se sobreescribirán los métodos SessionContext como se vió en la página anterior.
  • Genera las Clases EJB:
    NOTA:
    En páginas anteriores ya vimos los pasos para generar las clases EJB.

. Implementar el Interface DAO:

No tenemos que implementar el interface DAO porque estámos utilizando la clase StoreAccessDAOImpl creada en la página anterior.

  • Ve a la clase StoreAccessDAOImpl y modifica la sentencia de la declaración de la clase, para que implemente el interface StoreAccessStateDAO, como se ve en el siguiente fragmento de código:

Ya se han implementado todos los métodos, sólo quedan por terminar los descriptores de despligue.

. Desplegar el Bean:

Antes de desplegar el bean tenemos que declarar unas cuantas etiquetas en la clase StoreAccessStateBean:

  • Añade la siguiente etiqueta a nivel de clase en el fichero StoreAccessStateBean:
    @ejb.resource-ref res-ref-name="jdbc/DefaultDS"
    res-type="javax.sql.Datasource"
    res-auth="Container"
    

    Esta etiqueta generará los descriptores de despliegue en ejb-jar.xml, ya que el bean tiene que saber a qué fuentes de datos va a conectarse, de qué tipo, etc. Esto generará estos descriptores:

  • Añade esta otra etiqueta al mismo nivel en el mismo fichero:
    @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 saber qué nombre JNDI tendrá la fuente de datos. Esto generará estos descriptores:

  • Añade esta otra etiqueta en el mismo sitio:
    @jboss.container-configuration name ="Standard Stateful SessionBean"
    

    Esta etiqueta generará los descriptores de despliegue en jboss.xml, ya que el servidor de aplicaciones tiene que saber qué configuración va a leer el bean con estado desde standardjboss.xml bajo /opt/jboss/jboss-3.2.1/server/all/conf/. Esto generará los siguientes descripores en jboss.xml:

    
    <session>
      <ejb-name>StoreAccessState</ejb-name>
      <jndi-name>StoreAccessStateBean</jndi-name>
      <configuration-name>Standard Stateful SessionBean</configuration-name>
      <resource-ref>
          <res-ref-name>jdbc/DefaultDS</res-ref-name>
          <jndi-name>java:/DefaultDS</jndi-name>
      </resource-ref>  
    </session>
    
    
    NOTA:
    Esta configuración es para que el bean de sesión con estado lea el contenedor de JBoss. JBoss viene con un timeout de 60 minutos para los beans de sesión con estado. Cambia el atributo <max-bean-life> a 120 segundos y reinicia el servidor. Como puedes ver en el siguiente fragmento de código del fichero /opt/jboss/jboss-3.2.1/servaer/all/conf/standardjboss.xml:
    
    <container-configuration>
      <container-name>Standard Stateful SessionBean</container-name>
        <call-logging>false</call-logging>
        <invoker-proxy-binding-name>stateful-rmi-invoker</invoker-proxy-binding-name>
        <container-interceptors>
         -------------------------------------------------------------------
         ----------------------------------------------------------------------
         ---------------------------------------------------------------------
         <container-cache-conf>
         <cache-policy>org.jboss.ejb.plugins.LRUStatefulContextCachePolicy</cache-policy>
           <cache-policy-conf>
               <min-capacity>50</min-capacity>
               <max-capacity>1000000</max-capacity>
               <!--remover-period>1800</remover-period-->
               <remover-period>120</remover-period>
    
               <max-bean-life>120</max-bean-life>
               <!-- By default Jboss comes withh 60 mins time out for stateful bean,change it
                    to 120 secs (2 mins) and restart the server to read this config.
               -->
               <!--max-bean-life>1800</max-bean-life-->
               <!-- 1800 secs = 30 mins -->
    
               <overager-period>300</overager-period>
               <max-bean-age>600</max-bean-age>
               <resizer-period>400</resizer-period>
               <max-cache-miss-period>60</max-cache-miss-period>
               <min-cache-miss-period>1</min-cache-miss-period>
               <cache-load-factor>0.75</cache-load-factor>
            </cache-policy-conf>
          </container-cache-conf>
         ----------------------------------------------------------------------
         ---------------------------------------------------------------------
    
    

Ahora, ya está todo terminado y ha llegado el momento de desplegar el bean.

  • Primero, regenera tus clases EJB como vimos en pasos anteriores y por última vez.
    NOTA:
    Hemos regenerado las clases una y otra vez para poder explicar cada paso y su resultado. Una vez que estés familiarizado con estos pasos sólo necesitas generar tus clases de vez en cuando. De cualquier modo, no afecta a tu implementación, por eso puedes (re)generar tus clases siempre que quieras.
  • Ve a la Vista Lomboz J2EE View y expande el nodo MyStore > MyStoreMgr, selecciona Jboss 3.2.1 ALL.
  • Pulsa con el botón derecho y selecciona Debug Sever en el menú desplegable.
  • Ve al nodo MyStoreMgr en la vista LombozJ2EE, pulsa con el botón derecho y selecciona Deploy en el menú desplegable.

Ahora espera un poco para ver el resultado del despliegue.

Si todo ha ido bien, obtendrás en la consola un mensaje como este:

Ya que hemos desplegado con éxito nuestro bean creemos un cliente de prueba, que llamará al método loginUser de StoreAccessStateBean.

. Crear un Test de Cliente:

  • Ve al nodo del proyecto MyStore, selecciona el nodo src y pulsa con el botón derecho.
  • Selecciona New en el menú desplegable y selecciona el Lomboz EJB Test Client Wizard:
  • Selecciona el nombre de paquete como au.com.tusc.client, el nombre como SessionStateClient y el Ejb Home como au.com.tusc.sessionState.StoreAccessStateHome y el Ejb Interface como au.com.tusc.sessionState.StoreAccessState:

    Esto generará los métodos de ayuda necesarios en la clase SessionStateClient y simplemente tendremos que llamar al método loginUser del bean.

  • Añade las siguientes líneas de código al método testBean:
    public void testBean() {
    
       String userID = null;
       try {
          au.com.tusc.sessionState.StoreAccessState myBean =
               getHome().create(userID);
          //--------------------------------------
          //This is the place you make your calls.
          //System.out.println(myBean.callYourMethod());
                            
          System.out.println("Request from client : ");
          userID = myBean.loginUser("ANDY","PASSWD");
          System.out.println("Reply from Server: Your userid is " + userID);
          myBean.setUserID(userID);
          System.out.println("Going to Sleep for 1 min ......................... " );
          
          Thread.sleep(60000); // sleep for 1 minute.
          System.out.println("Reply from bean after 1min  " + myBean.getUserID());
          
          System.out.println("Again going to Sleep for 3 min ......................... " );
          Thread.sleep(180000); // sleep for 3 minute.
          System.out.println("Resuming after 3 mins ......................... " );
          //Next statement will not be executed as bean will timeout on the server side
          //resulting in exception.
          System.out.println("Reply from bean after 2mins  " + myBean.getUserID());
      
       }catch (InterruptedException e) {
            
       }catch (NoSuchObjectException e) {
          System.out.println("No Such Object Exception caught  ");
       } catch (RemoteException e) {
          System.out.println("Remote Exception caught  ");
       } catch (CreateException e) {
          e.printStackTrace();
       } catch (NamingException e) {
          e.printStackTrace();
       } catch (EJBException e) {
          System.out.println("EJB Exception caught  ");
       }
    }
    
    public static void main(String[] args) {
       SessionStateClient test = new SessionStateClient();
       test.testBean();
    }
    

. Probar el Cliente

  • Ahora, para poder probar el cliente, selecciona el nodo SessionStateClient ve al menú superior y selecciona el icono con el hombre corriendo.
  • Selecciona Run as > Java Application

Ahora bajo la consola, si obtienes una respuesta U2 para ANDY, antes de un minuto, pero después de 3 minutos se captura una NoSuchObjectException significará que el bean con estado está funcionando con éxito.

 
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