En la lecci�n anterior, el servlet buscaba y creaba un bean de sesi�n para realizar el c�lculo de un bono, y luego buscaba y creaba un bean de entidad para almacenar el valor del bono y el n�mero de la seuridad social asociado. Esta lecci�n modifica el ejemplo para que el bean de sesi�n busque y cree el bean de entidad. Como el bean de sesi�n y el de entidad trabajan juntos, est�n empaquetados en un s�lo fichero JAR para su despliegue.
Nota: Algunas personas tienen problemas con esta lecci�n al trabajar 2 beans en un fichero JAR. Si sucede esto, podemos borrar el fichero JAR con los dos beans y poner cada bean en su propio fichero JAR. Podr�amos necesitar parar y rearrancar el servidor y las herramientas antes de poder generar el SQL y desplegar. |
�Cambiar el Bean de Sesi�n
En esta lecci�n y como se ve en la siguiente figura el bean de entidad es un cliente del bean de sesi�n. Esto significa que el bean de entidad obtiene sus datos del bean del sesi�n en vez de BonusServlet como lo hizo en la . Por eso, se modifica el m�todo calcBonus del bean de sesi�n para tomar el n�mero de la seguridad social como un par�metro y crear el bean de entidad.

�CalcHome
El interface CalcHome no se modifica. Tiene el mismo m�todo create que devuelve un ejemplar del interface remoto.
package Beans; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface CalcHome extends EJBHome { public Calc create() throws CreateException, RemoteException; }
�Calc
El m�todo calcBonus del interface Calc se ha modificado para tomar el n�mero de la seguridad social como par�metro. Por eso CalcBean puede pasar el bono y el n�mero de la seguridad social al bean de entidad despu�s de calcular el valor del bono. Se a�ade un nuevo m�todo getRecord para que CalcBean peuda encontrar el bean de entidad por sus clave primaria (el n�mero de la seguridad social).
Tambi�n, la firma del m�todo calcBonus lanza DuplicateKeyException y CreateException. Esto es por lo que BonusServlet puede capturar y manejar cualquiera de estas condiciones de excepci�n. DuplicateKeyException desciende de CreateException. Si dise�amos el m�todo calcBonus para lanzar DuplicateKeyException , pero capturamos CreateException, DuplicateKeyException no se lanzar�. El atajo es hacer que calcBonus lance DuplicateKeyException y CreateException .
package Beans; import javax.ejb.EJBObject; import java.rmi.RemoteException; import javax.ejb.DuplicateKeyException; import javax.ejb.CreateException; public interface Calc extends EJBObject { public Bonus calcBonus(int multiplier, double bonus, String socsec) throws RemoteException, DuplicateKeyException, CreateException; public Bonus getRecord(String socsec) throws RemoteException; }
�CalcBean
El c�digo para crear el bean de entidad se ha movido desde BonusServlet hasta calcBonus para que el bono y el n�mero de la seguridad social puedan escribirse en el bean de entidad despu�s de haber calculado el bono. La variable homebonus es una variable de ejemplar para que pueda ser usada en el m�todo calcBonus para buscar el bean de entidad y en el m�todo getRecord para localizar el bean de entidad correspondiente al n�mero de la seguridad social.
package Beans; import java.rmi.RemoteException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import javax.ejb.DuplicateKeyException; import javax.ejb.CreateException; public class CalcBean implements SessionBean { BonusHome homebonus; //Throw DuplicateKeyException and CreateException //so BonusServlet can catch and handle these //exception conditions. public Bonus calcBonus(int multiplier, double bonus, String socsec) throws DuplicateKeyException, CreateException { Bonus theBonus = null; double calc = (multiplier*bonus); try { InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("bonus"); homebonus = (BonusHome) PortableRemoteObject.narrow( objref, BonusHome.class); } catch (Exception NamingException) { NamingException.printStackTrace(); } //Store data in entity bean try { theBonus = homebonus.create(calc, socsec); } catch (java.rmi.RemoteException e) { String message = e.getMessage(); e.printStackTrace(); } return theBonus; } public Bonus getRecord(String socsec) { Bonus record = null; //Use primary key to retrieve data from entity bean try { record = homebonus.findByPrimaryKey(socsec); } catch (java.rmi.RemoteException e) { String message = e.getMessage(); } catch (javax.ejb.FinderException e) { e.printStackTrace(); } return record; } public void ejbCreate() { } public void setSessionContext( SessionContext context){ } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } public void ejbLoad() { } public void ejbStore() { } }
�Cambiar el Servlet
El programa BonusServlet es muy similar a la versi�n de la Lecci�n anterior con algunos cambios en los m�todos init y doGet. El m�todo init para esta secci�n s�lo busca el bean de sesi�n.
public class BonusServlet extends HttpServlet { CalcHome homecalc; //Need Bonus variables because CalcBean methods //called in the doGet method return instances //of type Bonus Bonus theBonus, record; public void init(ServletConfig config) throws ServletException{ try { InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("calcs"); homecalc = (CalcHome) PortableRemoteObject.narrow( objref, CalcHome.class); } catch (Exception NamingException) { NamingException.printStackTrace(); } }
La sentencia try del m�todo doGet calcula el bono, crea el interface home del bean de sesi�n y llama a los m�todos calcBonus y getRecord. Si el m�todo se completa con �xito, se devuelve una p�gina HTML que muestra los datos recuperados desde el bean de entidad. Si el m�todo calcBonus lanza una DuplicateKeyException, se devuelve una p�gina HTML mostrando el n�mero de la seguridad social y el multiplicador pasados, y un mensaje de excepci�n, Duplicate primary key.
Como en la lecci�n anterior, la sentencia catch captura y maneja valores de claves primarias duplicadas (n�meros de la seguridad social).
try { Calc theCalculation; //Retrieve Bonus and Social Security Information String strMult = request.getParameter( "MULTIPLIER");//Calculate bonus Integer integerMult = new Integer(strMult); multiplier = integerMult.intValue(); socsec = request.getParameter("SOCSEC"); //Calculate bonus double bonus = 100.00; theCalculation = homecalc.create(); //Call session bean //Pass 3 parameters:multiplier, bonus, and socsec theBonus = theCalculation.calcBonus( multiplier, bonus, socsec); record = theCalculation.getRecord(socsec); //Display data returned by session bean out.println("<H1>Bonus Calculation</H1>"); out.println("<P>Soc Sec retrieved: " + record.getSocSec() + "<P>"); out.println("<P>Bonus Amount retrieved: " + record.getBonus() + "<P>"); out.println("</BODY></HTML>"); } catch (javax.ejb.DuplicateKeyException e) { String message = e.getMessage(); out.println("<H1>Bonus Calculation</H1>"); out.println("<P>Soc Sec passed in: " + socsec + "<P>"); out.println("<P>Multiplier passed in: " + multiplier + "<P>"); out.println("</BODY></HTML>"); } catch (Exception CreateException) { CreateException.printStackTrace(); }
�Compilar
Primero compilamos el bean de sesi�n y el servlet. Puedes referirte a la primera lecci�n para ver la configuraci�n del path y del classpath y m�s informaci�n sobre d�nde situar los ficheros fuente.
�Compilar el Bean de Sesi�n
Unix
#!/bin/sh cd /home/monicap/J2EE J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2.1 CPATH=.:$J2EE_HOME/lib/j2ee.jar javac -d . -classpath "$CPATH" Beans/CalcBean.java Beans/CalcHome.java Beans/Calc.java
Windows
cd \home\monicap\J2EE set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2.1 set CPATH=.;%J2EE_HOME%\lib\j2ee.jar javac -d . -classpath %CPATH% Beans/CalcBean.java Beans/CalcHome.java Beans/Calc.java
�Compilar el Servlet
Unix:
cd /home/monicap/J2EE/ClientCode J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2 CPATH=.:$J2EE_HOME/lib/j2ee.jar: /home/monicap/J2EE javac -d . -classpath "$CPATH" BonusServlet.java
Windows:
cd \home\monicap\J2EE\ClientCode set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2 set CPATH=.;%J2EE_HOME%\lib\j2ee.jar:\home\monicap\J2EE javac -d . -classpath %CPATH% BonusServlet.java
�Arrancar la Plataforma y las Herramientas
Para ejecutar este ejemplo, necesitamos arrancar el servidor J2EE, la herramienta Deploy y la base de datos Cloudscape. En diferentes ventanas, tecleamos los siguientes comandos.
j2ee -verbose deploytool cloudscape -start
Si esto no funciona, tecleamos esto desde el directorior J2EE:
Unix
j2sdkee1.2.1/bin/j2ee -verbose j2sdkee1.2.1/bin/deploytool j2sdkee1.2.1/bin/cloudscape -start
Windows
j2sdkee1.2.1\bin\j2ee -verbose j2sdkee1.2.1\bin\deploytool j2sdkee1.2.1\bin\cloudscape -start
�Ensamblar la Aplicaci�n
Los pasos de esta secci�n incluyen:
- Crear una nueva aplicaci�n J2EE.
- Crear un nuevo componente Web.
- Empaquetar los Beans de Sesi�n y de Entidad en un fichero JAR.
�Crear una Nueva aplicaci�n J2EE
En vez de actualizar la aplicaci�n J2EE de las lecciones anteriores, estos pasos crean una nueva aplicaci�n J2EE.
Borrar BonusApp:
- Pulsamos BonusApp para que se ilumine
- Seleccionamos Delete desde el men� Edit
Crear 2BeansApp :
- Desde el men� File, seleccionamos New Application .
- Pulsamos con el bot�n derecho del rat�n en el campo Application Display Name. Aparecer� 2BeansApp como nombre.
- Pulsamos el bot�n Browse para abrir el selector de ficheros y seleccionar la localizaci�n donde queremos grabar el fichero EAR de la aplicaci�n.
Selector de ficheros New Application :
- Localizamos el directorio donde queremos situar el fichero de aplicaci�n EAR.
- En este ejemplo, el directorio es /export/home/monicap/J2EE.
- En el campo File name, tecleamos 2BeansApp.ear.
- Pulsamos New Application.
- Pulsamos OK.
�Crear un nuevo componente Web.
Ahora, veremos los pasos para crear el fichero WAR. Estos pasos que se presentaron en la primera lecci�n se sumarizan abajo.
Con 2BeansApp seleccionado:
File Menu:
- Seleccionamos New Web Component.
Introducci�n :
- Leemos y Pulsamos Next
War File General Properties :
- Especificamos BonusWar para el nombre.
- Pulsamos Add
- Vamos al directorio ClientCode y a�adimos bonus.html
- Pulsamos Next
- Vamos al directorio ClientCode y a�adimos BonusServlet.class
- Pulsamos Finish.
War File General Properties :
- Pulsamos Next.
Choose Component Type: .
- Nos aseguramos de seleccionar Describe a servlet.
- Pulsamos Next.
Component General Properties :
- Hacemos la clase de servlet BonusServlet.
- Hacemos el nombre de display BonusServlet .
- Pulsamos Next.
Component Initialization Parameters.
- Pulsamos Next.
Component Aliases :
- Especificamos BonusAlias
- Pulsamos Finish.
Ventana Inspecting:
- Seleccionamos Web Context
- Especificamos BonusRoot.
�Empaquetar los Beans de Sesi�n y de Entidad en un Fichero JAR
En esta lecci�n, pondremos los beans de sesi�n y de entidad en el mismo fichero JAR. Para hacer esto, primero creamos el fichero JAR con s�lo el bean de sesi�n, y luego le a�adimos el bean de entidad.
Crear JAR con el Bean de Sesi�n
Con 2BeansApp seleccionado,
Men� File:
- Seleccionamos New Enterprise Bean.
Introducci�n :
- Leemos y pulsamos Next .
EJB JAR :
- Nos aseguramos de que 2BeansApp se muestra en el campo Enterprise Bean will go in .
- Especificamos 2BeansJar como nombre.
- Pulsamos Add (el m�s cercano a la ventana Contents).
- Cambiamos el directorio para que el directorio Beans muestre su contenido.
- Seleccionamos Calc.class
- Pulsamos Add .
- Seleccionamos CalcBean.class
- Pulsamos Add .
- Seleccionamos CalcHome.class
- Pulsamos Add.
Clases Enterprise Bean JAR :
- Nos aseguramos de que vemos Beans/Calc.class , Beans/CalcHome.class, y Beans/CalcBean.class en la pantalla.
- Pulsamos OK.
EJB JAR :
- Pulsamos Next.
General :
- CalcBean es el nombre de la clase, Beans.CalcHome es el interface Home, y Beans.Calc es el interface remoto.
- Introducimos CalcBean como nomre de display.
- Pulsamos session and stateless.
- Pulsamos Next.
Entradas de Entorno:
- Pulsamos Next. Este sencillo bean de sesi�n no usa propiedades (entradas de entorno)
Referencias a Beans Enterprise:
- Pulsamos Next. Las referencias se manejar�n durante el despliegue mejor que aqu�.
Referencias a Recursos:
- Pulsamos Next. Este sencillo bean de sesi�n no busca ning�n objeto de base de datos o sesi�n JavaMail�.
Seguridad:
- Pulsamos Next. Este sencillo bean de sesi�n no usa roles de seguridad.
Control de Transaciones :
- Seleccionamos Container-managed transactions (si no lo est� ya).
- En la lista de abajo hacemos necesarios calcBonus, y getRecord. Esto significa que el contenedor arranca una nueva transaci�n antes de ejecutar estos m�todos. La transaci�n se env�a justo antes de que los m�todos terminen.
- Pulsamos Next.
Revisar configuraciones:
- Pulsamos Finish .
Local Applications:
- Seleccionamos 2BeansApp .
- En la ventana Inspecting seleccionamos JNDI names, le damos el nombre CalcBean JNDI de calcs, y pulsamos la tecla Return.
A�adir el Bean de Entidad
Con 2BeansApp seleccionado,
File Menu:
- Seleccionamos New Enterprise Bean
Introduction :
- Leemos y pulsamos Next.
EJB JAR :
- Nos aseguramos de que 2BeansJar se muestra en el campo Enterprise Bean will go in . Esta selecci�n a�adir� el nuevo bean al fichero JAR existente en lugar de ponerlo en un nuevo fichero JAR.
- Pulsamos Add (el m�s cercano a la ventana Contents).
- Cambiamos el directorio para que el directorio Beans muestre su contenido.
- Seleccionamos Bonus.class
- Pulsamos Add .
- Seleccionamos BonusBean.class
- Pulsamos Add .
- Seleccionamos BonusHome.class
- Pulsamos Add.
Enterprise Bean JAR classes :
- Nos aseguramos de ver Beans/Bonus.class , Beans/BonusHome.class, y Beans/BonusBean.class en el display.
- Pulsamos OK.
EJB JAR :
- Pulsamos Next .
General :
- Nos aseguramos de que Beans.BonusBean es el nombre de la clase, Beans.BonusHome es el interface Home, y Beans.Bonus es el interface remoto.
- Introducimos BonusBean como nombre de pantalla.
- Pulsamos Entity .
- Pulsamos Next .
Entity Settings:
- Seleccionamos Container managed persistence .
- En la ventana inferior, marcamos bonus y socsec. la clase de clave primaria es java.lang.String, y el nombre del campo de la clave primaria es socsec. Observa que la clave primara tiene que ser un tipo de clase. Los tipos primitivos no son v�lidos para claves primarias.
- Pulsamos Next .
Environment Entries:
- Pulsamos Next . Este sencillo bean no usa propiedades (entradas de entorno).
Enterprise Bean References:
- Pulsamos Next. Este sencillo bean no referencia otros beans enterprise.
Resource References:
- Pulsamos Next. Este sencillo bean no busca objetos de base de datos ni sesiones JavaMail�.
Seguridad:
- Pulsamos Next. Este sencillo Bean no usa roles de seguridad.
Control de Transaciones :
- Seleccionamos Container-managed transactions (si no lo est� ya)
- En la lista de abajo hacemos necesarios create , findByPrimaryKey, getBonus y getSocSec. Esto significa que el contenedor arrancar� una nueva transaci�n antes de ejecutar estos m�todos. La transaci�n se env�a justo antes de que los m�todos terminen.
- Pulsamos Next .
Review Settings:
- Pulsamos Finish .
Local Applications:
- Seleccionamos 2BeansApp .
- En la ventana Inspecting, seleccionamos JNDI names, dando a BonusBean el nombre JNDI de bonus y a CalcBean el nombre JNDI de calcs
- Pulsamos la tecla Return despu�s de cada entrada.
Antes de poder desplegar la aplicaci�n J2EE, necesitamos especificar las configuraciones de despliegue para el bean de entidad y generar el SQL:
Ventana Local Applications:
- Seleccionamos BonusBean.
Ventana Inspecting:
- Seleccionamos Entity
- Pulsamos el bot�n Deployment Settings inferior derecha.
Ventana Deployment Settings:
- Especificar jdbc/Cloudscape (con una C may�sculas en Cloudscape) para el nombre JNDI de la base de datos.
- Pulsamos Return
- Nos aseguramos de que las cajas Create table on deploy y Delete table on Deploy est�n marcadas.
- Ahora pulsamos Generate SQL.
Nota: Si obtenemos un error de que la conexi�n fue rechazada, arrancamos de nuevo la base de datos como se describe en Arrancar la Plataforma y las Herramientas. |
Cuando se complete la generaci�n del SQL,
- Seleccionamos el m�todo findByPrimaryKey en la caja EJB method.
- Aparecer� una sentencia SQL a la derecha. Deber�a ser SELECT "socsec" FROM "BonusBeanTable" WHERE "socsec"=?.
El interrogante representa el par�metro pasado para el m�todo findByPrimaryKey. - Pulsamos OK.
�Verificar y Desplegar la Aplicaci�n J2EE
Antes de desplegar la aplicaci�n, es una buena idea ejecutar el verificador. El verificador mostrar� los errores en los componentes de la aplicaci�n como m�todos inexistentes que el compilador no captura.
Nota: Si obtenemos un error Save cuando verificamos o desplegamos, debemos parar todo y rearrancar el servidor y las herramientas. |
Verificar:
- Con 2BeansApp seleccionado, elegimos Verifier desde el men� Tools.
- En el di�logo que aparece, pulsamos OK. La ventana deber�a decir que no hay ning�n fallo.
- Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicaci�n.
Nota: En la versi�n 1.2.1 del software podr�amos obtener un error tests app.WebURI. Esto significa que la herramienta DeployTool no puso la extensi�n .war al fichero WAR durante su creacci�n. Es un error menor y la aplicaci�n J2EE se despliega sin problemas. |
Desplegar:
- Desde el men� Tools, elegimos Deploy Application. Se mostrar� una caja de di�logo Deploy BonusApp.
- Verificar que la selecci�n de Target Server es un host local o el nombre de un host donde se est� ejecutando el servidor J2EE.
Nota: No marcamos la caja "Return Client Jar". El �nico momento en que debemos chequear esta caja es cuando usamos persistencia controlada por el bean o desplegamos una aplicaci�n solitaria para el programa cliente. Este ejemplo usa un servlet y una p�gina HTML por lo que no debe est�r marcada. Esta caja crea un fichero JAR con toda la informaci�n de despliegue necesaria para una aplicaci�n solitaria. |
- Pulsamos Next .
- Nos aseguramos de que los nombres JNDI muestran calcs para CalcBean y bonus para BonusBean. Si no es as�, tecleamos los nombres JNDI nosotros mismos, y pulsamos la tecla Return.
- Pulsamos Next. Nos aseguramos de que el nombre Context Root muestra BonusRoot. Si no es as�, lo tecleamos nosotros mismos y pulsamos la tecla Return.
- Pulsamos Next .
- Pulsamos Finish para empezar el despliegue. Se mostrar� una caja de di�logo que mostrar� el estado de la operaci�n de despliegue.
- Cuando se haya completado, las tres barras de la izquierda se habr�n sombreado completamente, como se ve en la siguiente figura. Cuando esto suceda pulsamos OK.

�Ejecutar la Aplicaci�n J2EE
El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la p�gina bonus.html apuntamos nuestros navegador a http://localhost:8000/BonusRoot/bonus.html, que es donde DeployTool puso el fichero HMTL.
Rellenamos un n�mero de la seguridad social y un m�ltiplicador, y pulsamos el bot�n Submit. BonusServlet procesa nuestros datos y devuelve una p�gina HTML con el bono calculado
Bonus Calculation Soc Sec retrieved: 777777777 Bonus Amount Retrieved: 200.0
Si volvemos al c�digo de bonus.html y cambiamos el multiplicador por 2, pero usamos el mismo n�mero de la seguridad social, veremos esto:
Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Duplicate primary key
�C�digo Fuente de los Ejemplos
Aqu� tienes un fichero Zip con los ficheros fuente de los ejemplos de esta p�gina: