Está en la página 1de 90

JAVA ENTER PRISE EDITION J2EE

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

Temario
1. Descripcin de la Arquitectura J2EE 1.1 Describir los principales elementos de la arquitectura J2EE. 1.2 Arquitectura para aplicaciones J2EE (definicin del contexto) 1.3 Modelo MVA 2. Descripcin del Componente EJB 2.1 SessionBean Aplicacin Cliente Multi-Capa Software J2EE y Configuracin Componentes de Aplicacin J2EE Crear la Pgina HTML Crear y Compilar el Bean de Sesin y el Servlet Ciclo de vida de SessionBean Arrancar el Servidor de Aplicaciones J2EE Aplicacin J2EE Crear la aplicacin J2EE Crear Componentes Web Especificar el Nombre JNDI y el Contexto Raz Verificar, Desplegar y Ejecutar la Aplicacin Actualizar el Cdigo de Componentes 2.2. EntityBean (EJB de tipo Entidad Ciclo de vida de EntityBean Crear el Bean de Entidad Cambiar el Servlet Compilar el Bean de Entidad y el Servlet Arrancar la Plataforma y las Herramientas Verificar, Desplegar y Ejecutar la Aplicacin 3. Comunicaciones entre Beans Enterprise 3.1 Cambiar el Bean de Sesin y el Servlet 3.2 Compilar el Bean de Sesin y el Servlet 3.2.1 Arrancar la Plataforma y las Herramientas 3.2.2 Ensamblar la Aplicacin J2EE 3.2.3 Verificar, Desplegar y Ejecutar la Aplicacin J2EE 4. Construccin de una sencilla aplicacin de J2EE 4.1 Como configurar el software para la ejecucin de una aplicacin J2EE 4.2 Construccin de un SessionBean 4.3 Construccin de un EntityBean 4.4 Construccin del Cliente

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

4.4.1 Servlets 4.4.2 JSPs Tecnologa JavaServer Pages (JSP) Crear la Pgina JSP Modificar bonus.html Eliminar el Fichero WAR Verificar, Desplegar y Ejecutar la Aplicacin J2EE Tecnologa JavaBeans Crear bonus.jsp Crear la Clase JavaBean Arrancar la Plataforma y las Herramientas Eliminar el Fichero WAR Crear el Nuevo Fichero WAR eXtensible Markup Language XML Marcar y manejar texto Modificar la clase JavaBean Los APIs SAX y DOM J2EE JDBC Ciclo de Vida del Bean Modificar cdigos Crear la tabla de la base de datos Eliminar el Fichero JAR Verificar, Desplegar y Ejecutar la aplicacin

Requisitos: Conocimientos de Modelamiento UML, Lenguaje Java Avanzado (haber realizado los cursos anteriores del programa), conocimientos de Arquitectura Cliente/Servidor, RMI, JSP, y Servlets. Dirigido a: Responsables de equipos tcnicos y de planificacin estratgica, expertos en arquitectura de sistemas y asesores tecnolgicos de departamentos de informtica y empresas independientes proveedoras de software. Duracin:40 horas cronolgicas

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

Un Sencillo Bean de Sesin Ejemplo de Aplicacin Cliente Multi-Capa Software J2EE y Configuracin Configuracin del Path y ClassPath Componentes de Aplicacin J2EE Crear la Pgina HTML Cdigo HTML Crear el Servlet Sentencias Import Mtodo init() Mtodo doGet Cdigo del Servlet Crear el Bean de Session CalcHome Calc CalcBean Compilar el Bean de Sesin y el Servlet Compilar el Bean de Session Compilar el Servlet Arrancar el Servidor de Aplicaciones J2EE Arrancar la Herramienta DeployTool DeployTool Ensamblar la Aplicacin J2EE Crear la aplicacin J2EE Crear el Bean de Sesin Crear Componentes Web Especificar el Nombre JNDI y el Contexto Raz Verificar y Desplegar la Aplicacin J2EE Ejecutar la Aplicacin J2EE Actualizar el Cdigo de Componentes Un Bean de Entidad Crear el Bean de Entidad BonusHome Bonus BonusBean Cambiar el Servlet Compilar Compilar el Bean de Entidad Compilar el Servlet Arrancar la Plataforma y las Herramientas Ensamblar y Desplegar Actualizar el Fichero de Aplicacin Crear el Bean de Entidad Verificar y Desplegar la aplicacin J2EE Ejecutar la Aplicacin J2EE

5 6 6 7 7 8 8 9 9 10 10 11 12 13 13 14 14 14 15 15 16 16 17 17 17 19 22 23 24 24 25 25 26 27 29 30 30 31 31 31 31 32 36 36

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

Comunicaciones entre Beans Cambiar el Bean de Sesin CalcHome Calc CalcBean Cambiar el Servlet Compilar Compilar el Bean de Sesin Compilar el Servlet Arrancar la Plataforma y las Herramientas Ensamblar la Aplicacin Crear una Nueva aplicacin J2EE Crear un nuevo componente Web. Empaquetar los Beans de Sesin y de Entidad en un Fichero JAR Verificar y Desplegar la Aplicacin J2EE Ejecutar la Aplicacin J2EE Tecnologa JavaServer Pages (JSP) Crear la Pgina JSP Comentarios Directivas Declaraciones Scriptlets Variables Predefinidas Expresiones Etiquetas Especificas de JSP Modificar bonus.html Arrancar la Plataforma y las Herramientas Eliminar el Fichero WAR Verificar y Desplegar la Aplicacin J2EE Ejecutar la Aplicacin J2EE Tecnologa JavaBeans Sobre el Ejemplo Crear bonus.jsp Especificar el JavaBean Obtener los Datos Pasar los Datos al JavaBean Recuperar los Datos desde el JavaBean Crear la Clase JavaBean Propiedades del Bean Constructor Mtodos Set Mtodos Get Arrancar la Plataforma y las Herramientas Eliminar el Fichero WAR Crear el Nuevo Fichero WAR Verificar y Desplegar la Aplicacin J2EE

38 38 38 39 39 40 42 42 42 43 43 43 44 45 48 49 51 51 52 53 53 53 54 54 54 55 55 56 57 58 59 59 61 62 62 62 63 63 64 65 65 66 67 68 68 69 5

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

Ejecutar la Aplicacin J2EE

70
71 71 72 72 72 74 74 74 76 77 77 77 78 78 79 79 80 80 80 85 86 87 87 87 88 89 91

XML - eXtensible Markup Language Marcar y Manejar Texto Modificar la Clase JavaBean Prlogo XML Documento Raz Nodos Hijos Otras Etiquetas XML Cdigo del JavaBean Los APIs SAX y DOM J2EE Actualizar y Ejecutar la Aplicacin JDBC Ciclo de Vida del Bean Modificar el cdigo de BonusBean Sentencias Import Variables de Ejemplar Mtodos de Negocio Mtodos de Ciclo de Vida Modificar el Cdigo de CalcBean y JBonusBean Crear la Tabla de la Base de Datos createTable.sql cloudTable.bat cloudTable.sh Eliminar el Fichero JAR Verificar y Desplegar la Aplicacin Ejecutar la Aplicacin

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

Capitulo I - Introduccin
Este manual presenta los APIs, las herramientas y los servicios que proporciona la Implementacin de Referencia de Java 2 Enterprise Edition (J2EE). EJB, es la adaptacin de un modelo de componente Java para servidores de bases de datos, Transacciones y aplicaciones. Cada uno de estos funciona como un contenedor para componentes EJB, los cuales se intenta que sean porttiles entre servidores y sistemas operativos. A excepcin del aspecto de la portabilidad, la idea tras el EJB es similar a aquella que Microsoft promovi con el Microsoft Transaction Server y tecnologas relacionadas para aislar a los desarrolladores de negocios de la complejidad de crear aplicaciones demasiado complicadas. Los desarrolladores escribirn componentes que requieran de servicios del contenedor EJB, y el servidor secundario descifrar que servicio puede proporcionar y cual deber ser enviado a otro servidor. "La idea es que escribir aplicaciones interrelacionadas es difcil, y EJB lo facilita".

Un Sencillo Bean de Sesin


Esta leccin nos presenta la programacin de aplicaciones J2EE, y el SDK J2EE mostrndonos como escribir una sencilla y pequea aplicacin Enterprise multi-capa que consiste en una pgina HTML, un servlet y un Bean de sesin.

El SDK J2EE es una definicin y especificacin operacional no comercial de la plataforma J2EE que Sun Microsystem a liberado para demostraciones, prototipos y usos educacionales. Viene con el servidor de aplicaciones J2EE, servidor Web, base de datos, los APIs J2EE, y un completo conjunto de herramientas de desarrollo. Nos iremos encontrando con estas caractersticas y herramientas segn vayamos avanzando en este tutorial.

Ejemplo de Aplicacin Cliente Multi-Capa


Est pequea aplicacin cliente de ejemplo acepta entrada de usuario a travs de un formulario HTML que invoca un servlet. El servlet usa el API JNDI (Java Naming and Directory Interface) para buscar un Bean de sesin que realice los clculos por l. Este ejemplo es una aplicacin pequea porque el servlet no ejecuta ninguna lgica de negocio. El sencillo clculo lo realiza un Bean de sesin que se ejecuta en el servidor de aplicaciones J2EE. Por eso el cliente es pequeo, porque no maneja el proceso; lo hace el Bean de sesin. Las aplicaciones multi-capa pueden consistir en 3 4 capas. Como se ve en, el ejemplo multi-capa tiene cuatro capas. La arquitectura de tres capas extiende al cliente estndar de dos capas y el modelo del servidor situando un servidor de aplicaciones multi-capa entre la aplicacin cliente no-basada-en-web y la base de datos final. La arquitectura de cuatro Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile 7

capas extiende el modelo de tres capas reemplazando la aplicacin cliente con un navegador Web y una pgina HTML potenciada con las tecnologas servlet/JavaServer Pages.

Mientras que esta leccin usa slo tres o cuatro capas, la siguiente leccin extiende este mismo ejemplo para acceder al servidor de base de datos en la cuarta capa. Lecciones posteriores adaptan el ejemplo para usar las tecnologas JavaServer Pages y Extensible Markup Language (XML).

Software J2EE y Configuracin


Las instrucciones asumen que J2EE y J2SE estn instalados en el directorio J2EE debajo del directorio home del usuario. Nota: Siempre que se utilice monicap en un nombre de path, tendrs que cambiarlo por tu nombre de usuario. Unix: /home/monicap/J2EE/j2sdkee1.2.1 /home/monicap/J2EE/jdk1.2.2 Windows: \home\monicap\J2EE\j2sdkee1.2.1 \home\monicap\J2EE\jdk1.2.2

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

Configuracin del Path y ClassPath


La descarga contiene el servidor de aplicaciones J2EE, la base de datos Cloudscape, un servidor Web que usa capas de socket seguras (SSL) tambin conocido como HTTP sobre HTTPS, herramientas de desarrollo y despliegue, y los APIs Java para Enterprise. Para usar estar caractersticas, debemos configurar las variables de entorno path y classpath como se describe aqu: Configuracin del Path La configuracin del Path hace accesibles las herramientas de desarrollo y despliegue desde cualquier lugar de nuestro sistema. Debemos asegurarnos de seleccionar estos path antes de cualquier otro path que pudiramos tener de viejas instalaciones del JDK. Unix: /home/monicap/J2EE/jdk1.2.2/bin /home/monicap/J2EE/j2sdkee1.2.1/bin Windows: \home\monicap\J2EE\jdk1.2.2\bin \home\monicap\J2EE\j2sdkee1.2.1\bin Configuracin del ClassPath La configuracin del ClassPath le dice a las herramientas de desarrollo y despliegue de Java 2 dnde encontrar las distintas libreras de clases que usa: Unix: /home/monicap/J2EE/j2sdkee1.2.1/lib/j2ee.jar Windows: \home\monicap\J2EE\j2sdkee1.2.1\lib\j2ee.jar

Componentes de Aplicacin J2EE


Los programadores de aplicaciones J2EE escriben componentes de aplicacin J2EE. Un componente J2EE es una unidad de software funcional auto-contenida que se ensambla dentro de una aplicacin J2EE y que se comunica con otros componentes de aplicacin. La especificacin J2EE define los siguientes componentes de aplicacin: Componentes de Aplicacin Cliente Componentes JavaBeans Enterprise Componentes Servlets y JavaServer Pages (tambin llamados componentes Web) Applets

En esta leccin, crearemos una aplicacin y dos componentes J2EE: un servlet y un Bean de sesin. El servlet est empaquetado con su fichero HTML en un fichero Web Archive (WAR), y las clases e interfaces del Bean de sesin estn empaquetadas en un fichero JAR. Los ficheros WAR y JAR se aaden a la aplicacin J2EE y se empaquetan dentro de un fichero Enterprise Archive (EAR) para probar, verificar y desplegar el entorno de produccin. Mientras estemos haciendo todos estos pasos para esta leccin, realmente estaremos realizando varias funciones diferentes. Escribir el cdigo del servlet y del Bean de sesin es una funcin de desarrollo, mientras que crear la aplicacin J2EE y aadir los componentes J2EE a una aplicacin es una funcin de ensamblaje. En realidad, estas funciones podran ser realizadas por diferentes personas de diferentes compaas. Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile 9

Crear la Pgina HTML


La pgina HTML para esta leccin se llama bonus.html. Su cdigo HTML est debajo de la , que muestra cmo vera la pgina HTML el usuario. El fichero bonus.html tiene dos campos de datos en los que usuario puede introducir un nmero de seguridad social y un multiplicador. Cuando el usuario pulsa el botn Submit, /cursos/j2ee/L1/clientcode/BonusServlet.javaBonusServlet.java recupera el dato del usuario, busca el Bean de sesin, y le pasa el dato del usuario al Bean de sesin. el Bean de sesin calcula un valor "bonus" y lo devuelve al servlet. El servlet devuelve otra pgina HTML con el valor del "bonus" para que lo vea el usuario.

La siguiente Figura muestra el flujo de los datos entre el navegador y el Bean de sesin. El Bean de sesin se ejecuta en el servidor de aplicaciones J2EE.

Cdigo HTML
Lo ms interesante sobre el cdigo del formulario HTML es el alias usado para invocar a BonusServlet . Cuando el usuario pulsa el botn Submit sobre el formulario HTML, se llama a BonusServlet porque se ha mapeado a BonusAlias durante el ensamblaje de la aplicacin descrito en Ensamblar la Aplicacin J2EE. El ejemplo asume que bonus.html est en el directorio /home/monicap/J2EE/ClientCode en UNIX. Aqu y desde ahora los usuarios de Windows pueden invertir las barras inclinadas para obtener los paths correctos para su plataforma: <HTML> <BODY BGCOLOR = "WHITE"> <BLOCKQUOTE>
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

10

<H3>Bonus Calculation</H3> <FORM METHOD="GET" ACTION="BonusAlias"> <P> Enter social security Number: <P> <INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT> <P> Enter Multiplier: <P> <INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT> <P> <INPUT TYPE="SUBMIT" VALUE="Submit"> <INPUT TYPE="RESET"> </FORM> </BLOCKQUOTE> </BODY> </HTML>

Crear el Servlet
El ejemplo asume que el fichero BonusServlet.java est en el directorio /home/monicap/J2EE/ClientCode en UNIX. Durante la ejecucin, el cdigo del servlet hace lo siguiente: Recupera los datos del usuario Busca el bean de sesin Le pasa los datos al bean de sesin Despus de recibir un valor de vuelta desde el bean de sesin, crea una pgina HTML para mostrar el valor devuelto al usuario.

La siguiente seccin describe las diferentes partes del cdigo del servlet

Sentencias Import
El cdigo del servlet empieza con sentencias import para los siguientes paquetes: javax.servlet, que contiene clases servlets genricas (independientes del protocolo). La clase HTTPServlet usa la clase ServletException de este paquete para indicar un problema en el servlet. javax.servlet.http, que contiene clases servelts HTTP. La clase HttpServlet est en este paquete. java.io para entrada y salida del sistema. La clase HttpServlet usa la clase IOException de este paquete para sealar que se ha producido una excepcin de algn tipo de entrada o salida. javax.naming para poder usar los APIs Java Naming and Directory Interface (JNDI) para buscar el interface home del bean de sesin. javax.rmi para buscar el interface home del bean de sesin y poner su objeto servidor remoto listo para las omunicaciones.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

11

Mtodo init()
El mtodo BonusServlet.init busca el interface home del bean de sesin y crea su ejemplar. El mtodo usa el nombre JNDI especificado durante el ensamblado de componentes ( calcs) para obtener una referencia al interface home por su nombre. La siguiente lnea pasa la referencia y la clase del interface home al mtodo PortableRemoteObject.narrow para asegurarse de que la referencia puede forzarse al tipo CalcHome. InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("calcs"); homecalc = (CalcHome)PortableRemoteObject.narrow(obj ref, CalcHome.class);

Mtodo doGet
La lista de parmetros de doGet toma un objeto request y un response. El navegador enva una peticin (request) al servlet y el servlet enva una respuesta (response) de vuelta al navegador. La implementacin del mtodo accede a informacin del objeto request para encontrar quin ha hecho la peticin, en qu formulario estn los datos de la peticin, y que cabeceras HTTP se enviarn, y usa el objeto response para crear una pgina HTML en respuesta a la peticin del navegador. El mtodo doGet lanza una IOException si hay algn problema con los datos de entrada o salida cuando maneja la peticin, y una ServletException si la peticin no se puede manejar. Para calcular el valor del bonus, el mtodo doGet crea el interface home y llama al mtodo calcBonus. public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String socsec = null; int multiplier = 0; double calc = 0.0; PrintWriter out; response.setContentType("text/html"); String title = "EJB Example"; out = response.getWriter(); out.println("<HTML><HEAD><TITLE>") out.println(title); out.println("</TITLE></HEAD><BODY>"); try{ //Retrieve Bonus and Social Security Information String strMult = request.getParameter( "MULTIPLIER"); Integer integerMult = new Integer(strMult); multiplier = integerMult.intValue(); socsec = request.getParameter("SOCSEC"); //Calculate bonus double bonus = 100.00; theCalculation = homecalc.create(); calc = theCalculation.calcBonus( multiplier, bonus); }catch(Exception CreateException){
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

12

CreateException.printStackTrace(); } //Display Data out.println("<H1>Bonus Calculation</H1>"); out.println("<P>Soc Sec: " + socsec + "<P>"); out.println("<P>Multiplier: " + multiplier + "<P>"); out.println("<P>Bonus Amount: " + calc + "<P>"); out.println("</BODY></HTML>"); out.close(); }

Cdigo del Servlet


Aqu est el cdigo completo: import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import javax.naming.*; import javax.rmi.PortableRemoteObject; import Beans.*; public class BonusServlet extends HttpServlet { CalcHome homecalc; public void init(ServletConfig config) throws ServletException{ //Look up home interface try{ InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("calcs"); homecalc = (CalcHome)PortableRemoteObject.narrow( objref, CalcHome.class); } catch (Exception NamingException) { NamingException.printStackTrace(); } } public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String socsec = null; int multiplier = 0; double calc = 0.0; PrintWriter out; response.setContentType("text/html"); String title = "EJB Example"; out = response.getWriter(); out.println("<HTML><HEAD><TITLE>"); out.println(title); out.println("</TITLE></HEAD><BODY>");
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

13

try{ Calc theCalculation; //Get Multiplier and Social Security Information String strMult = request.getParameter("MULTIPLIER"); Integer integerMult = new Integer(strMult); multiplier = integerMult.intValue(); socsec = request.getParameter("SOCSEC"); //Calculate bonus double bonus = 100.00; theCalculation = homecalc.create(); calc = theCalculation.calcBonus(multiplier, bonus); } catch(Exception CreateException){ CreateException.printStackTrace(); } //Display Data out.println("<H1>Bonus Calculation</H1>"); out.println("<P>Soc Sec: " + socsec + "<P>"); out.println("<P>Multiplier: " + multiplier + "<P>"); out.println("<P>Bonus Amount: " + calc + "<P>"); out.println("</BODY></HTML>"); out.close(); } public void destroy() { System.out.println("Destroy"); } }

Crear el Bean de Session


Un bean de sesin representa una conversacin temporal con un cliente. Si el servidor o el cliente, se cuelgan, el bean de sesin y sus datos se van. En contraste, los beans de entidad son persistentes y representan datos en una base de datos. Si el servidor o el cliente se bloquean, los servicios relacionados aseguran que los datos del bean de entidad se graban. La siguiente Figura muestra como funcionan el servlet y el bean de sesin como una aplicacin J2EE completa una vez que se han ensamblado y desplegado. El contenedor, mostrado en la caja sombreada, es el interface entre el bean de sesin y las funcionalidades especificas de la plataforma de bajo-nivel que soporta el bean de sesin. El contenedor se crea durante el despliegue.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

14

La siguiente seccin muestra el cdigo del bean de sesin. El ejemplo asume que los ficheros /cursos/j2ee/L1/Beans/CalcBean.javaCalcBean.java , /cursos/j2ee/L1/Beans/Calc.java Calc.java, y /cursos/j2ee/L1/Beans/CalcHome.java CalcHome.java estn situados en el directorio /home/monicap La sentencia package Beans en la parte superior del interface CalcBean y los ficheros de clases es el mismo nombre que el nombre de este directorio. Cuando se compilen estos ficheros, se hara desde el directorio superior Beans y el nombre del paquete Beans (o directorio) se pretende que apunte al interface y los ficheros class compilados. Compilar el Bean de Sesin. Nota: Este ejemplo muestra cmo escribir un bean de sesin, pero tambin es posible comprar beans enterprise a un proveedor y ensamblarlos dentro de una aplicacin J2EE.

CalcHome
BonusServlet no trabaja directamente con el bean de sesin, sino que crea un ejemplar de su interface home. El interface home extiende EJBHome y tiene un mtodo create para crear el bean de sesin en su contendor. Se lanzar una CreateException si no se puede crear el bean de sesin y una RemoteException si ocurre una excepcin relacionada con las comunicaciones durante la ejecucin del mtodo remoto. package Beans; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface CalcHome extends EJBHome { Calc create() throws CreateException, RemoteException; }

Calc
Cuando se crea el interface home, el servidor de aplicaciones J2EE crea el interface remoto y el bean de sesin. El interface remoto extiende EJBObject declara el mtodo calcBonus para el clculo del valor del bonos. Este mtodo requiere que se lance una javax.rmi.RemoteException, y est implementado por la clase CalcBean. package Beans; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Calc extends EJBObject { public double calcBonus(int multiplier, double bonus) throws RemoteException; }
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

15

CalcBean
La clase del bean de sesin implementa el interface SessionBean y proporciona el comportamiento para el mtodo calcBonus. Los mtodos setSessionContext y ejbCreate son llamados en este orden por el contendor despus de que BonusServlet llame al mtodo create CalcHome. Los mtodos vacos son del inteface SessionBean. Estos mtodos los llama el contenedor del bean. No tenemos que proporcionar comportamiento para estos mtodos a menos que necesitemos funcionalidades adicionales, por ejemplo cuando el bean es aadido o eliminado de su contenedor. package Beans; import java.rmi.RemoteException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; public class CalcBean implements SessionBean { public double calcBonus(int multiplier, double bonus) { double calc = (multiplier*bonus); return calc; } //These methods are described in more //detail in Lesson 2 public void ejbCreate() { } public void setSessionContext( SessionContext ctx) { } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } public void ejbLoad() { } public void ejbStore() { } }

Compilar el Bean de Sesin y el Servlet


Para ahorrarnos tecleado, la forma ms sencilla para compilar el bean de sesin y el servlet es con un script (en Unix) o un fichero batch (en Windows).

Compilar el Bean de Session


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
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

16

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 #!/bin/sh cd /home/monicap/J2EE/ClientCode J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2.1 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 el Servidor de Aplicaciones J2EE


Necesitamos arrancar el servidor de aplicaciones J2EE para desplegar y ejecutar el ejemplo. El comando para arrancar el servidor est en el directorio bin debajo de nuestra instalacin J2EE. Si tenemos el path configurado para que lea el directorio bin, vamos directamente al directorio J2EE (entonces nuestra versin real corresponde con lo que veremos en el texto) y tecleamos: j2ee verbose Nota: Algunas veces el servidor J2EE no arranca si estamos ejecutando Outlook Si esto no funciona, tecleamos lo siguiente desde el directorio J2EE: Unix: j2sdkee1.2.1/bin/j2ee -verbose Windows: j2sdkee1.2.1\bin\j2ee -verbose La opcin verbose imprime mensajes de informacin en la lnea de comandos cuando el servidor arranca. Cuando veamos J2EE server startup complete , podemos arrancar la herramienta de despliegue. Por ahora, podemos ignorar los otros mensajes que aparecen.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

17

Arrancar la Herramienta DeployTool


Para ensamblar y desplegar la aplicacin J2EE, tenemos que arrancar la herramienta deploytool. Si tenemos el path configurado para que lea el directorio bin, vamos directamente al directorio J2EE (entonces nuestra versin real corresponde con lo que veremos en el texto) y tecleamos: deploytool Si esto no funciona, hacemos lo siguiente desde el directorio J2EE: Unix: j2sdkee1.2.1/bin/deploytool Windows: j2sdkee1.2.1\bin\deploytool Notas: Si ocurre un error de acceso a memoria mientras arrancamos deploytool , aadimos una variable de entorno llamada JAVA_FONTS y seleccionamos el path a c: \<font directory> . Por ejemplo c:\winnt\fonts. Tambin, si se encuentra una NullPointerException para BasicFileChooserUI cuando se arranca deploytool, debemos asegurarnos de no arrancar la herramienta desde el directorio raz (es decir c:\ ). Si la ejecutamos desde cualquier otro lugar, como el directorio bin de nuestra instalacin j2sdkee1.2, no encontraremos este problema.

DeployTool
El herramienta DeployTool mostrada en la siguiente figura tiene cuatro ventanas principales. La ventana "Local Aplications" muestra las aplicaciones J2EE y sus componentes. La ventana "Inspecting" muestra informacin sobre la aplicacin o componentes seleccionados. La ventana "Servers" nos dice si el servidor de aplicaciones se est ejecutando en un host local. Y la ventana "Server Aplications" nos dice qu aplicaciones tenemos instaladas. Cuando sigamos los pasos para ensamblar la aplicacin de ejemplo J2EE, veremos que todas estas ventanas nos muestran informacin.

Nota:
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

18

A la derecha de la ventana Server Applications hay un botn gris Uninstall. Despus de desplegar la aplicacin, veremos la aplicacin listada en esta ventana. Podemos pulsar sobre Uninstall para desinstalarla, hacerle cambios, y reinstalarla sin tener que parar y rearrancar el servidor de aplicaciones.

Ensamblar la Aplicacin J2EE


Ensamblar una aplicacin J2EE implica crear una nueva aplicacin, y aadirle los componentes de aplicacin. Aqu tenemos un sumario de los pasos para ensamblar, que se describen abajo con ms detalle. 1. 2. 3. 4. 5. Crear una nueva aplicacin J2EE (BonusApp.ear). Crear un nuevo bean enterprise (CalcBean.jar). Crear un nuevo componente web (Bonus.war). Especificar un nombre JNDI para el bean enterprise ( calcs). Especificar el contexto raz para la aplicacin J2EE (BonusRoot ).

Crear la aplicacin J2EE


Los componentes J2EE se ensamblan dentro de ficheros (EAR) "Enterprise Archive". Menu File : Seleccionamos New Application . Caja de dilogo New Application: Tecleamos BonusApp.ear para el Application File Name. Pulsamos el botn derecho del ratn en el campo Application Display Name. BonusApp aparece en el nombre. Pulsamos el botn Browse para abrir el selector de ficheros para seleccionar la localizacin donde queremos grabar el fichero EAR

Selector de Ficheros New Application: Localizamos el directorio donde queremos situar el fichero EAR de la aplicacin. En este ejemplo, este directorio es /home/monicap/J2EE . En el campo File name, tecleamos BonusApp.ear. Pulsamos sobre New Application . Pulsamos sobre OK.

En la ventana de Local Applications ahora aparecer " Bonusapp.ear", y en la ventana Inspector a la derecha muestyra el nombre, la localizacin y la informacin de contenidos para BonusApp . La meta informacin mostrada en la ventrana contents describe el fichero JAR y la aplicacin J2EE, y prorporciona informacin de tiempo de ejecucin sobre la aplicacin.

Crear el Bean de Sesin


Los beans Enterprise (tanto de entidad como de sesin) se empaquetan en un fichero JAR. Men File: Seleccionamos New Enterprise Bean. Arrancar el New Enterprise Bean Wizard y mostrar un digolo de introduccin que sumariza los pasos que vamos a tomar. Despus de leerlos, pulsamos sobre Next . Caja de Dilogo EJB JAR: Especificamos la siguiente informacin: Enterprise Bean will go in : BonusApp Display name: CalcJar Description: Un sencillo Bean de sesin que calcula un bonus y tiene un mtodo. Pulsamos sobre Add. Hay dos botones en esta pantalla. No aseguramos de pulsar el segundo que est cerca de la ventana Contents.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

19

Caja de Dilogo Add Files to .JAR: vamos al directorio J2EE. Podemos teclear el nombre del path o usar el navegador para obetenerlo. Una vez en el directorio J2EE, hacemos doble click sobre beans para mostrar el contenido del directorio beans. Selecionamos Calc.class . Pulsamos sobre Add . Seleccionamos CalcHome.class . Pulsamos sobre Add . Seleccionamos CalcBean.class . Pulsamos sobre Add .

Nota Importante: La caja de dilogo Add Contents to .JAR se debera parecer a la de la figura siguiente. Las clases Enterprise Bean JAR se deberan mostrar con el prefijo del nombre de directorio Beans. Pulsamos OK. Ahora deberamos estar de nuevo en la caja de dilogo EJB JAR. Beans/Calc.class , Beans/CalcHome.class, y Beans/CalcBean.class deberan aparecer en la ventana Contents. Pulsamos Next.

Caja de dilogo General : Seleccionamos la siguiente informacin: classname: Beans.CalcBean Home interface: Beans.CalcHome Remote interface: Beans.Calc Bean type: Session y Stateless Especificamos el nombre (el nombre que aparece cuando el fichero JAR se aade a BonusApp en la ventana de "Local Applications"), y proporcionamos una descripcin para los contenidos del ficheros JAR. Display Name: CalcBean Description: Este fichero JAR contiene el bean de sesin CalcBean. Pulsamos sobre Next .

Caja de Dilogo Environment Entries: Este ejemplo no hace uso de las propiedades (entradas de entorno) pero nosotros si podramos: Pulsamos sobre Finish . Verificar que el fichero JAR se aadido realmente a la aplicacin J2EE: Vamos a la ventana "Local Applications" Pulsamos el grfico gris en frente de BonusApp . Veremos el fichero JAR CalcJar. Pulsamos el grfico gris en frente de CalcJar para ver el bean de sesin CalcBean.

Crear Componentes Web


Los componentes Web (servlets, o JavaServer Pages) se empaquetan dentro de un fichero Web Archive (WAR). Men File : Seleccionamos New Web Component . Se arrancar el New Web Component Wizard y mostrar una ventana que sumariza los pasos que vamos a tomar. Despus de leerlos, pulsamos sobre Next . Caja de dilogo WAR File General Properties : Proporcionamos la siguiente informacin:

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

20

WAR file: BonusApp Display name: BonusWar Description: Este fichero war contiene un servlet y una pgina HTML Pulsamos Add .

Caja de Dilogo Add Contents to WAR: Vamos el directorio ClientCode tecleando ClientCode despus de J2EE en el campo Root Directory. Seleccioamos bonus.html. Debemos asegurarnos de que WAR contents muestra el listado como bonus.html sin el directorio ClientCode precediendo al nombre. Pulsamos sobre Add .

Nota: Debemos asegurarnos de aadir bonus.html antes de aadir BonusServlet.class

Pulsamos sobre Next . Elegimos de nuevo el directorio ClientCode. Seleccionamos BonusServlet.class. Debemos asegurarnos de que WAR contents muestra el nombre de BonusServlet.class sin el directorio precediendo el nombre. Pulsamos sobre Add . Caja de Digolo Contents to WAR: La pantalla se debera parecer a la de la siguiente figura

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

21

Pulsamos Finish . Caja de digolo WAR File General Properties : Pulsamos Next . Caja de dilogo Choose Component Type: Selecccionamos Servlet (si no est ya seleccionado) Puslamos Next . Caja de Dilogo Component General Properties : Nos aseguramos de que BonusServlet est seleccionado para la clase Servlet. Introducimos un nombre ( BonusServlet ) y una descripcin. Podemos ignornar las selecciones de Startup y load sequence aqu porque este ejemplo slo usa un servlet. Caja de dilogo Component Initialization Parameters : Pulsamos Next . BonusServlet no usa ningn parmetro de inicializacin. Caja de dilogo Component Aliases:
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

22

Pulsamos Add . Tecleamos BonusAlias y pulsamos Return . Este es el mismo nombre de alias que pusimos en el campo ACTION del formulario HTML embebido en el fichero bonus.html. Pulsamos Finish .

En el panel de contenido, podemos ver que el fichero WAR contiene un fichero XML con informacin estructural y de atributos sobre la aplicacin web. el fichero bonus.html, y el fichero class BonusServlet. El formato del fichero WAR es donde van todas las clases servlet en un punto de entrada con Web-INF/classes. Sin embargo, cuando se despliega el fichero WAR, la clase BonusServlet se sita en un directorio raz de contexto bajo public_html. Esta situacin es la convencin parra servidores web compatibles con Servlet 2.2. Para cambiar el nombre o la descripcin: Ponemos el cursor en el campo apropiado en la ventana Lo cambiamos segn nuestros deseos Pulsamos la tecla Return para que las ediciones tengan efecto.

Especificar el Nombre JNDI y el Contexto Raz


Antes de poder desplegar la aplicacin BonusApp y sus componentes, tenemos que especificar el nombre JNDI que BonusServlet usa para buscar el bean de sesin CalcBean, y especificar un directorio de contexto raz donde el desplegador pondr los componentes web. Nombre JNDI: Seleccionamos el fichero BonusApp en la ventana "Local Applications". La ventana "Inspecting" muestra pestaas en la parte superior, y una de esas pestaas es JNDI Names. Seleccionamos Select JNDI. La ventana "Inspecting" muestra una pantalla con tres columnas y una fila. CalcBean se ve en la columna central. En la columna ms a la derecha bajo el nombre JNDI, tecleamos calc. Este nombre JNDI es el mismo nombre JNDI pasado al mtodo BonusServlet.lookup. Pulsamos la tecla Return.

Contexto Raz: Pulsamos la pestaa Web Context en la parte superior de la ventana Inspecting. Veremos BonusWar en la columna de la izquierda. Tecleamos BonusRoot en la columna de la derecha Pulsamos la tecla Return. Durante el despliegue se crea el directorio BonusRoot bajo el directorio public_html en nuestra instalacin J2sdkee1.2 , y los ficheros bonus.html y BonusServlet se copian como muestra en la siguiente figura:

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

23

Alias:

En la ventana LocalApp, pulsamos BonusWar y luego BonusServlet Pulsamos la pestaa Aliases de la parte superior de la ventana Inspecting. Deberamos ver BonusAlias en el campo. Si BonusAlias no est ah, lo tecleamos y pulsamos Return.

Verificar y Desplegar la Aplicacin J2EE


Antes de desplegar la aplicacin, es una buena idea ejecutar el verificador. El verificador nos mostrar errores en los componentes de la aplicacin como un mtodo no existente en el bean que el compilador no captura. Verificar: Con BonusApp seleccionado, elegimos Verifier desde el men Tools. En el dilogo que aparece, pulsamos OK. La ventana nos debera decir si no han fallado los tests. Cerramos la ventana del verificador porque ya estamos listos para desplegar la aplicacin.

Nota: En la versin 1.2 podramos obtener un error tests app.WebURI. Esto significa que la herramienta de desarrollo no puso una extensin .war al fichero WAR durante su creacin. Este es un bug menor y la apliacin J2EE se despliega bien sin notarlo. Desplegar: Desde el men Tools, elegimos Deploy Application . Se mostrar una caja de dilogo Deploy BonusApp. Debemos verificar que la seleccin Target Server es o localhost o el nombre del servidor donde se est ejecutando el J2EE.

Nota: No debemos seleccionar el check box Return Client Jar. La nica vez que necesitamos seleccionar este check box es cuando despleguemos una aplicacin solitaria para el programa cliente. Este ejemplo usa un servlet y una pgina HTML por eso no debemos seleccionarlo. Seleccionar este check box crea un fichero Jar con la informacin de despliegue necesaria para una aplicacin solitaria. Pulsamos Next. Nos aseguramos de que el nombre JNDI muestra calcs. Si no lo hace, lo tecleamos nosotros mismos y pulsamos la tecla Return. Pulsamos Next. Nos aseguramos de que el nombre Context Root muestra BonusRoot. Si no lo hace, lo tecleamos nosotros y pulsamos la tecla Return. Pulsamos Next . Pulsamos Finish para empezar el despliegue. Aparecer una caja de dilogo que mostrar el estado de la operacin de despliegue.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

24

Cuando est completa, las tres barras de la izquierda estrn completamente sombreadas, como se ve en la siguiente figura. Cuando esto suceda, pulsamos OK.

Ejecutar la Aplicacin J2EE


El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la pgina bonus.html apuntamos nuestro navegador a http://localhost:8000/BonusRoot/bonus.html, que es donde DeployTool puso el fichero HMTL. Nota: Si necesitamos usar un puerto diferente porque el puerto 8000 est siendo utilizado por otra cosa, editamos el fichero web.properties en el directorio ~/J2EE/j2sdkee1.2/config y arrancamos de nuevo el servidor J2EE. Rellenamos un nmero de seguridad social. Rellenamos un multiplicador. Pulsamos el botn Submit. BonusServlet procesa nuestros datos y devuelve una pgina HTML con el clculo del bono.

Bonus Calculation Soc Sec: 777777777 Multiplier: 25 Bonus Amount 2500.0

Actualizar el Cdigo de Componentes


El men Tools tiene dos opciones de inters. Son Update Application Files y Update and Redeploy Application. Estas opciones nos permiten cambiar el cdigo y redesplegar nuestra aplicacin con facilidad. Simplemente hacemos los cambios en el cdigo, lo recompilamos, y elegimos una de estas opciones del men. Update Application Files actualiza los ficheros de la aplicacin con nuestro nuevo cdigo. En este punto podemos verificar la aplicacin o desplegarla. Update and Redeploy Application actualiza los ficheros de la aplicacin con nuestro nuevo cdigo y redespliega la aplicacin sin ejecutar el verificador.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

25

Capitulo II - Aadir un Bean de Entidad


Este capitulo ampla el ejemplo de la leccin anterior para usar un bean de entidad. BonusServlet llama al bean de entidad para grabar informacin sobre el nmero de la seguridad social y el bono y recuperarlo desde una tabla de la base de datos. Este funcionalidad de acceso a la base de datos aade la cuarta capa y la capa final al pequeo cliente empezado en la leccin anterior. El SDK J2EE viene con una base de datos Cloudscape, y no necesitamos configuracin adicional en nuestro entorno para el bean de entidad. De echo en este jemplo, no escribimos ningn cdigo SQL o JDBC para crear las operaciones de acceso a la base de datos. La tabla y el cdigo SQL se generan con la herramienta de Despliegue durante en el ensamble y el despliegue. La leccin sobre Tecnologa JDBC y Persistencia Manejada por el Bean nos ensear como escribir cdigo SQL para un bean de entidad.

Crear el Bean de Entidad


Un bean de entidad representa datos persistentes almacenados en una fila de una tabla de una base de datos. Cuando se crea un bean de entidad, los datos se escriben en la fila apropiada de la tabla, y si se actualizan los datos de un bean de entidad, los datos de la fila apropiada de la tabla tambin se actualizan. La creacin de la tabla de la base de datos y la actualizacin de las filas ocurre sin escribir nada de cdigo SQL o JDBC. Los datos de un bean de entidad son persistentes porque sobreviven a los crashs. Si ocurre un crash mientras se estn actualizando los datos de un bean de entidad, estos datos son restaurados automticamente al estado de la ltima transaccin enviada a la base de datos. si ocurre un crash en medio de una transaccin a la base de datos, la transaccin se "deshace" para evitar que un envo parcial corrompa los datos.

BonusHome
La principal diferencia entre el bean de sesin CalcHome de la leccin anterior y el bean de entidad BonusHome de esta leccin es el mtodo findByPrimaryKey. Este mtodo de bsqueda toma la clave primaria como un parmetro. En este ejemplo, la clave primara es el nmero de la seguridad social, que se usa para recuperar la fila con el valor de la clave primaria que corresponde con el nmero de la seguridad social pasado a este mtodo. El mtodo create toma el valor del bono y de la clave primaria como parmetros. Cuando BonusServlet ejemplariza el interface home y llama a su mtodo create, el contenedor crea un ejemplar de BonusBean y llama a su mtodo ejbCreate. Los mtodos BonusHome.create y BonusBean.ejbCreate deben tener la misma firma , para que los valores del bono y la clave primaria puedan ser pasados desde el interface home al bean de entidad mediante el contenedor del bean de entidad. Si una fila para una clave primada dada (nmero de seguridad social) ya existe, se lanza una java.rmi.RemoteException que es manejada por el cdigo cliente BonusServlet. package Beans; import java.rmi.RemoteException; import javax.ejb.CreateException;

import javax.ejb.FinderException; import javax.ejb.EJBHome;


Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

26

public interface BonusHome extends EJBHome { public Bonus create(double bonus, String socsec) throws CreateException, RemoteException; public Bonus findByPrimaryKey(String socsec) throws FinderException, RemoteException; }

Bonus
Despus de crear el interface home, el contenedor crea el interface remoto y el bean de entidad. El interface Bonus declara los mtodos getBonus y getSocSec para que el servlet pueda recuperar los datos desde el bean de entidad package Beans; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Bonus extends EJBObject { public double getBonus() throws RemoteException; public String getSocSec() throws RemoteException; }

BonusBean
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

27

BonusBean es un bean de entidad controlado por contenedor. Esto significa que el contenedor maneja la persistencia de los datos y el control de las transaciones sin tener que escribir cdigo para transferir datos entre el bean de entidad y la base de datos o definir paquetes de transacciones. Si por alguna razn queremos que el bean de entidad maneje su propia persistencia o las transacciones, podramos proporcionar implementaciones para algunos de los mtodos vacos mostrados en el cdigo de BonusBean de abajo. Cuando BonusServlet llama a BonusHome.create, el contenedor llama al mtodo BonusBean.setEntityContext. El ejemplar de EntityContext pasado al mtodo setEntityContext tiene mtodos que permiten al bean devolver una referencia a s mismo o para obtener su clave primaria. Luego, el contenedor, llama al mtodo ejbCreate. Este mtodo asigna datos a las variables de ejemplar del bean, y luego el contenedor escribe los datos en la base de datos. Se llama al mtodo ejbPostCreate despus de ejbCreate y realiza cualquier proceso necesario despus de que se cree el bean. Este sencillo ejemplo no hace procesamiento postcreacin. Los otros mtodos vacos son mtodos de retrollamada usados por el contenedor para notificar al bean algn evento que va a ocurrir. Podramos proporcionar comportamiento para algunos de estos mtodos si estmos usando persistencia controlada por el bean, y otros si necesitamos proporcionar limpieza especfica del bean u operaciones de limpieza. Estas operaciones de limpieza e inicializacin tienen lugar en momentos especficos durante el ciclo de vida del bean, y el contenedor se lo notifica al bean y llama al mtodo aplicable en el momento apropiado. Aqu tenemos una breve descripcin de los mtodos vacos: Los mtodos ejbPassivate y ejbActivate los llama el contenedor antes de que el contenedor mueva el bean de su almacenamiento. Este proceso es similar al concepto de intercambio de una pgina de memoria virtual entre la memoria y el disco. El contenedor llama al mtodo ejbRemove si el interface home tiene el correspondiente mtodo remove que es llamado por el cliente. Los mtodos ejbLoad y ejbStore los llama el contenedor antes de que se sincronize el estado del bean con la base de datos subyacente.

Los mtodos getBonus y getSocSec son llamados por los clientes para recuperar datos almacenados en variables de ejemplar. Este ejemplo no tiene mtodos del tipo set< type >, pero si los tuviera, el cliente podra llamarlos para modificar los datos de las variables de ejemplar del bean. Cualquier cambio hecho en una variable de ejemplar resulta en una actualizacin de la fila de la tabla de la base de datos subyacente. package Beans; import import import import java.rmi.RemoteException; javax.ejb.CreateException; javax.ejb.EntityBean; javax.ejb.EntityContext;

public class BonusBean implements EntityBean { public double bonus; public String socsec; private EntityContext ctx; public double getBonus() { return this.bonus; } public String getSocSec() { return this.socsec; }
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

28

public String ejbCreate(double bonus, String socsec) throws CreateException{ //Called by container after setEntityContext this.socsec=socsec; this.bonus=bonus; return null; } public void ejbPostCreate(double bonus, String socsec) { //Called by container after ejbCreate } //These next methods are callback methods that //are called by the container to notify the //Bean some event is about to occur public void ejbActivate() { //Called by container before Bean //swapped into memory } public void ejbPassivate() { //Called by container before //Bean swapped into storage } public void ejbRemove() throws RemoteException { //Called by container before //data removed from database } public void ejbLoad() { //Called by container to //refresh entity Bean's state } public void ejbStore() { //Called by container to save //Bean's state to database } public void setEntityContext(EntityContext ctx){ //Called by container to set Bean context } public void unsetEntityContext(){ //Called by container to unset Bean context } }

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

29

Cambiar el Servlet
El cdigo de esta leccin es muy similar al de la pgina anterior con cambios en los mtodos init y doGet. El mtodo init de esta leccin busca el bean de sesin CalcBean, y el bean de entidad BonusBean. public class BonusServlet extends HttpServlet { CalcHome homecalc; BonusHome homebonus; Bonus theBonus, record; public void init(ServletConfig config) throws ServletException{ try { InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("bonus"); Object objref2 = ctx.lookup("calcs"); homebonus=( BonusHome)PortableRemoteObject.narrow( objref, BonusHome.class); homecalc=(CalcHome) PortableRemoteObject.narrow( objref2, CalcHome.class); } catch (Exception NamingException) { NamingException.printStackTrace(); } } La sentencia try en el mtodo doGet crea los interfaces home de CalcBean y BonusBean. Despus de llamar a calcBonus para calcular el bono, se llama al mtodo BonusHome.create para crear un ejemplar del bean de entidad y la correspondiente fila en la tabla de la base de datos subyacente. Despus de crear la tabla, se llama al mtodo BonusHome.findByPrimaryKey para recuperar el mismo registro por su clave primaria (nmero de la seguridad social). Luego, se devuelve una pgina HTML al navegador mostrado los datos pasados originalmente, el bono calculado, y los datos recuperados desde la fila de tabla de la base de datos. La sentencia catch captura y maneja los valores de claves primaria duplicados (nmeros de seguridad social. La tabla de la base de datos subyacente no puede tener dos filas con la misma clave primaria, por eso si pasamos el mismo nmero de la seguridad social, el servlet captura el error antes de intentar crear el bean de entidad. En el evento de una clave duplicada, el servlet devuelve una pgina HTML con los datos pasados originalmente, el bono calculado, y un mensaje de error de clave duplicada: 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(); calc = theCalculation.calcBonus( multiplier, bonus); //Create row in table
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

30

theBonus = homebonus.create(calc, socsec); record = homebonus.findByPrimaryKey(socsec); //Display data out.println("<H1>Bonus Calculation</H1>"); out.println("<P>Soc Sec passed in: " + theBonus.getSocSec() + "<P>"); out.println("<P>Multiplier passed in: " + multiplier + "<P>"); out.println("<P>Bonus Amount calculated: " + theBonus.getBonus() + "<P>"); out.println("<P>Soc Sec retrieved: " + record.getSocSec() + "<P>"); out.println("<P>Bonus Amount retrieved: " + record.getBonus() + "<P>"); out.println("</BODY></HTML>"); //Catch duplicate key error } catch (javax.ejb.DuplicateKeyException e) { String message = e.getMessage(); //Display data 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("<P>Bonus Amount calculated: " + calc + "<P>"); out.println("<P>" + message + "<P>"); out.println("</BODY></HTML>"); } catch (Exception CreateException) { CreateException.printStackTrace(); } }

Compilar
Primero, compilamos el Bean de entidad y el servlet. Puedes volver a la leccin anterior para ver la configuracin del path, classpath y dnde situar los ficheros fuentes.

Compilar el Bean de Entidad


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/BonusBean.java Beans/BonusHome.java Beans/Bonus.java Windows cd \home\monicap\J2EE set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2.1
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

31

set CPATH=.;%J2EE_HOME%\lib\j2ee.jar javac -d . -classpath %CPATH% Beans/BonusBean.java Bean s/BonusHome.java Beans/Bonus.java

Compilar el Servlet
Unix: cd /home/monicap/J2EE/ClientCode J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2.1 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.1 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 directorio 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 y Desplegar
Los pasos de esta seccin son: Actualizar el Fichero de Aplicacin Crear el Bean de Entidad

Actualizar el Fichero de Aplicacin

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

32

El archivo web (WAR) contiene BonusServlet y bonus.html. Como hemos modificado BonusServlet, tenemos que actualizar la aplicacin J2EE con el nuevo cdigo del servlet. Ventana Local Applicatons: Iluminamos la aplicacin BonusApp. Men Tools Menu: Seleccionamos Update Application Files .

Nota: Se desinstalar automticamente la aplicacin BonusApp de la leccin anterior.

Crear el Bean de Entidad


Los pasos para crear el EJB JAR para el bean de entidad son muy similares a los pasos del bean de sesin cubiertos en la leccin anterior. Sin embargo, hay algunas diferencias, y se explican aqu: Nota: En esta leccin, el bean de entidad va en un ficjero JAR separado del bean de sesin para continuar el ejemplo de la leccin anterior con el menor nmero de cambios. Sin embargo, como estos beans tienen funcionalidades relacionadas podramos empaquetarlos y desplegarlos en el mismo fichero JAR. Vermos como hacer esto en la siguiente leccin. Menu File: Seleccionamos New Enterprise Bean.

Introduccin : Leer y Pulsar Next

EJB JAR : Nos aseguramos de que BonusApp se ve en Enterprise Bean will go in field . Especificamos BonusJar como nombre. Pulsamos Add (el ms cercano a la ventana Contents).

Aadir Componentes al JAR: Cambiamos el directorio para que el directorio de beans muestre su contenido. Seleccionamos Bonus.class Pulsamos Add. Selecionamos BonusBean.class Pulsamos Add. Seleccionamos BonusHome.class Pulsamos Add. Pulsamos OK.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

33

EJB JAR: Pulsamos Next .

General : Beans.BonusBean es el nombre de la clase. Beans.BonusHome es el interface Home. Beans.Bonus es el interface Remoto. Introducimos BonusBean como nombre a mostrar. Pulsamos Entity . Pulsamos Next .

Configuracin Entity: Seleccionamos Container-Managed persistence . En la ventana inferior, marcamos bonus y socsec . Especificamos java.lang.String para la clase de la clave primaria. Observa que la clave primaria tiene que ser un tipo de clase. Los tipos primitivos no pueden ser claves primaria. Especificamos socsec para el nombre de campo de la clave primaria. Pulsamos Next .

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

34

Entradas de Entorno: Pulsamos Next. Este sencillo bean de entidad no usa propiedades (entradas de entorno). Referencias a Beans Enterprise: Pulsamos Next. Este sencillo bean de entidad no referencia otros beans enterprise. Referencias a Recursos: Pulsamos Next. Este sencillo bean de entidad no busca un objeto database o JavaMail session. Seguridad: Pulsamos Next. Este sencillo bean de entidad no usa roles de seguridad. Control de Transaccin : Seleccionamos Container-managed transactions (si no est ya seleccionado). En la lista hacemos que sean requeridos create, findByPrimaryKey, getBonus y getSocSec. Esto significa que el contenedor empieza una nueva transaccin antes de ejecutar estos mtodos. Las transacciones se envan justo antes de que los mtodos terminen.

Pulsamos Next . Pulsamos Finish .

Aplicaciones Locales: Seleccionamos BonusApp . En la ventana Inspecting, seleccionamos JNDI names La damos a BonusBean el nombre JNDI de bonus Pulsamos la tecla Return

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

35

Antes de poder desplegar la aplicacin J2EE, necesitamos especificar las condiciones de despliegue para el bean de entidad y generar el SQL. Aqu est cmo hacerlo: Ventana Local Applications: Seleccionamos BonusBean . Ventana Inspecting: Seleccionamos Entity Pulsamos el botn Deployment Settings de la parte inferior izquierda. Configuracin de Despliegue: Especificamos jdbc/Cloudscape (con una C mauscula 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 estn marcadas. Ahora pulsamos Generate SQL .

Nota: Si obtenemos un error de que la conexin fue rechazada, arrancamos la base de datos como se describe en Arrancar la Plataforma y las Herramientas

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

36

Cuando se complete la generacin de SQL, seleccionamos el mtodo findByPrimaryKey en la caja EJB method. Aparecer una secuencia SQL a la derecha. Debera leerse SELECT "socsec" FROM "BonusBeanTable" WHERE "socsec"=?. El interrogante representa el parmetro pasado por el mtodo findByPrimaryKey. Pulsamos OK.

Verificar y Desplegar la aplicacin J2EE


Verificar: Con BonusApp seleccionado, elegimos Verifier desde el men Tools. En el dilogo que aparece, pulsamos OK. La ventana debera decirnos que no ha fallado ningn test. Cerramos la ventana del verificador porque ya estamos listos para desplegar la aplicacin.

Nota: En la versin 1.2 del software podra obtener un error tests app.WebURI. La Aplicacin J2EE se desplegar de todas formas. Despliegue: En el Men Tools: Seleccionamos Tools.Deploy Application.

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 aplicacin solitaria para el programa cliente. Este ejemplo usa un servlet y una pgina HTML por lo que no debe estr marcada. Esta caja crea un fichero JAR con toda la informacin de despliegue necesaria para una aplicacin solitaria. Pulsamos Next. Nos aseguramos de que JNDI names muestra calcs para CalcBean y bonus para BonusBean . Tecleamos cualquier nombre JNDI que no est y pulsamos la tecla Return. Pulsamos Next. Nos aseguramos que el nombre Context Root muestra BonusRoot. Si no lo hace, lo tecleamos nosotros mismos y pulsamos la tecla Return. Pulsamos Next. Pulsamos Finish para empezar el despliegue. Cuando se haya completado el despliegue, pulsamos OK.

Ejecutar la Aplicacin J2EE


El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la pgina bonus.html apuntamos nuestros navegador a http://localhost:8000/BonusRoot/bonus.html, que es donde DeployTool puso el fichero HMTL. Rellenamos un nmero de la seguridad social y un mltiplicador, y pulsamos el botn Submit. BonusServlet procesa nuestros datos y devuelve una pgina HTML con el bono calculado. Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 25 Bonus Amount calculated: 2500.0 Soc Sec retrieved: 7777777777 Bonus Amount retrieved: 2500.0
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

37

Si volvemos al cdigo de bonus.html y cambiamos el multiplicador por 2, pero usamos el mismo nmero de la seguridad social, veremos esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Bonus Amount calculated: 200.0 Duplicate primary key.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

38

Capitulo III - Comunicaciones entre Beans


En el capitulo anterior, el servlet buscaba y creaba un bean de sesin para realizar el clculo de un bono, y luego buscaba y creaba un bean de entidad para almacenar el valor del bono y el nmero de la seuridad social asociado. Este capitulo modifica el ejemplo para que el bean de sesin busque y cree el bean de entidad. Como el bean de sesin y el de entidad trabajan juntos, estn empaquetados en un slo fichero JAR para su despliegue. Nota: Algunas personas tienen problemas con esta leccin 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. Podramos necesitar parar y rearrancar el servidor y las herramientas antes de poder generar el SQL y desplegar.

Cambiar el Bean de Sesin


En esta leccin y como se ve en la siguiente figura el bean de entidad es un cliente del bean de sesin. Esto significa que el bean de entidad obtiene sus datos del bean del sesin en vez de BonusServlet como lo hizo en la . Por eso, se modifica el mtodo calcBonus del bean de sesin para tomar el nmero de la seguridad social como un parmetro y crear el bean de entidad.

CalcHome
El interface CalcHome no se modifica. Tiene el mismo mtodo 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; }

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

39

Calc
El mtodo calcBonus del interface Calc se ha modificado para tomar el nmero de la seguridad social como parmetro. Por eso CalcBean puede pasar el bono y el nmero de la seguridad social al bean de entidad despus de calcular el valor del bono. Se aade un nuevo mtodo getRecord para que CalcBean peuda encontrar el bean de entidad por sus clave primaria (el nmero de la seguridad social). Tambin, la firma del mtodo calcBonus lanza DuplicateKeyException y CreateException. Esto es por lo que BonusServlet puede capturar y manejar cualquiera de estas condiciones de excepcin. DuplicateKeyException desciende de CreateException. Si diseamos el mtodo 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 cdigo para crear el bean de entidad se ha movido desde BonusServlet hasta calcBonus para que el bono y el nmero de la seguridad social puedan escribirse en el bean de entidad despus de haber calculado el bono. La variable homebonus es una variable de ejemplar para que pueda ser usada en el mtodo calcBonus para buscar el bean de entidad y en el mtodo getRecord para localizar el bean de entidad correspondiente al nmero de la seguridad social. package Beans; import import import import import import import java.rmi.RemoteException; javax.ejb.SessionBean; javax.ejb.SessionContext; javax.naming.InitialContext; javax.rmi.PortableRemoteObject; javax.ejb.DuplicateKeyException; javax.ejb.CreateException;

public class CalcBean implements SessionBean { BonusHome homebonus; //Throw DuplicateKeyException and CreateException //so BonusServlet can catch and handle these //exception conditions.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

40

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 versin de la Leccin anterior con algunos cambios en los mtodos init y doGet. El mtodo init para esta seccin slo busca el bean de sesin.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

41

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 mtodo doGet calcula el bono, crea el interface home del bean de sesin y llama a los mtodos calcBonus y getRecord. Si el mtodo se completa con xito, se devuelve una pgina HTML que muestra los datos recuperados desde el bean de entidad. Si el mtodo calcBonus lanza una DuplicateKeyException, se devuelve una pgina HTML mostrando el nmero de la seguridad social y el multiplicador pasados, y un mensaje de excepcin, Duplicate primary key. Como en la leccin anterior, la sentencia catch captura y maneja valores de claves primarias duplicadas (nmeros 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();
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

42

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 sesin y el servlet. Puedes referirte a la primera leccin para ver la configuracin del path y del classpath y ms informacin sobre dnde situar los ficheros fuente.

Compilar el Bean de Sesin


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

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

43

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 Aplicacin
Los pasos de esta seccin incluyen: Crear una nueva aplicacin J2EE. Crear un nuevo componente Web. Empaquetar los Beans de Sesin y de Entidad en un fichero JAR.

Crear una Nueva aplicacin J2EE


En vez de actualizar la aplicacin J2EE de las lecciones anteriores, estos pasos crean una nueva aplicacin 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 botn derecho del ratn en el campo Application Display Name. Aparecer 2BeansApp como nombre. Pulsamos el botn Browse para abrir el selector de ficheros y seleccionar la localizacin donde queremos grabar el fichero EAR de la aplicacin.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

44

Selector de ficheros New Application : Localizamos el directorio donde queremos situar el fichero de aplicacin 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 leccin se sumarizan abajo. Con 2BeansApp seleccionado: File Menu: Seleccionamos New Web Component.

Introduccin : Leemos y Pulsamos Next

War File General Properties : Especificamos BonusWar para el nombre. Pulsamos Add Vamos al directorio ClientCode y aadimos bonus.html Pulsamos Next Vamos al directorio ClientCode y aadimos 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:
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

45

Seleccionamos Web Context Especificamos BonusRoot.

Empaquetar los Beans de Sesin y de Entidad en un Fichero JAR


En esta leccin, pondremos los beans de sesin y de entidad en el mismo fichero JAR. Para hacer esto, primero creamos el fichero JAR con slo el bean de sesin, y luego le aadimos el bean de entidad. Crear JAR con el Bean de Sesin Con 2BeansApp seleccionado, Men File: Seleccionamos New Enterprise Bean. Introduccin : 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 ms 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 sesin no usa propiedades (entradas de entorno) Referencias a Beans Enterprise: Pulsamos Next. Las referencias se manejarn durante el despliegue mejor que aqu.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

46

Referencias a Recursos: Pulsamos Next. Este sencillo bean de sesin no busca ningn objeto de base de datos o sesin JavaMail. Seguridad: Pulsamos Next. Este sencillo bean de sesin 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 transacin antes de ejecutar estos mtodos. La transacin se enva justo antes de que los mtodos 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. Aadir 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 seleccin aadir el nuevo bean al fichero JAR existente en lugar de ponerlo en un nuevo fichero JAR. Pulsamos Add (el ms 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 :
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

47

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 vlidos 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 transacin antes de ejecutar estos mtodos. La transacin se enva justo antes de que los mtodos 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 despus de cada entrada. Antes de poder desplegar la aplicacin 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 botn Deployment Settings inferior derecha.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

48

Ventana Deployment Settings: Especificar jdbc/Cloudscape (con una C maysculas 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 estn marcadas. Ahora pulsamos Generate SQL . Nota: Si obtenemos un error de que la conexin fue rechazada, arrancamos de nuevo la base de datos como se describe en Arrancar la Plataforma y las Herramientas. Cuando se complete la generacin del SQL, Seleccionamos el mtodo findByPrimaryKey en la caja EJB method. Aparecer una sentencia SQL a la derecha. Debera ser SELECT "socsec" FROM "BonusBeanTable" WHERE "socsec"=?. El interrogante representa el parmetro pasado para el mtodo findByPrimaryKey. Pulsamos OK.

Verificar y Desplegar la Aplicacin J2EE


Antes de desplegar la aplicacin, es una buena idea ejecutar el verificador. El verificador mostrar los errores en los componentes de la aplicacin como mtodos 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 dilogo que aparece, pulsamos OK. La ventana debera decir que no hay ningn fallo. Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicacin.

Nota: En la versin 1.2.1 del software podramos obtener un error tests app.WebURI. Esto significa que la herramienta DeployTool no puso la extensin .war al fichero WAR durante su creaccin. Es un error menor y la aplicacin J2EE se despliega sin problemas. Desplegar: Desde el men Tools, elegimos Deploy Application. Se mostrar una caja de dilogo Deploy BonusApp. Verificar que la seleccin 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 aplicacin solitaria para el programa cliente. Este ejemplo usa un servlet y una pgina HTML por lo que no debe estr marcada. Esta caja crea un fichero JAR con toda la informacin de despliegue necesaria para una aplicacin solitaria. Pulsamos Next .
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

49

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 dilogo que mostrar el estado de la operacin de despliegue. Cuando se haya completado, las tres barras de la izquierda se habrn sombreado completamente, como se ve en la siguiente figura. Cuando esto suceda pulsamos OK

Ejecutar la Aplicacin J2EE


El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la pgina bonus.html apuntamos nuestros navegador a http://localhost:8000/BonusRoot/bonus.html, que es donde DeployTool puso el fichero HMTL. Rellenamos un nmero de la seguridad social y un mltiplicador, y pulsamos el botn Submit. BonusServlet procesa nuestros datos y devuelve una pgina HTML con el bono calculado Bonus Calculation Soc Sec retrieved: 777777777 Bonus Amount Retrieved: 200.0 Si volvemos al cdigo de bonus.html y cambiamos el multiplicador por 2, pero usamos el mismo nmero de la seguridad social, veremos esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Duplicate primary key
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

50

Capitulo IV - Tecnologa JavaServer Pages (JSP)


La tecnologa JavaServer Pages (JSP) nos permite poner segmentos de cdigo servlet directamente dentro de una pgina HTML esttica. Cuando el navegador carga una pgina JSP, se ejecuta el cdigo del servlet y el servidor de aplicaciones crea, compila, carga y ejecuta un servlet en segundo plano para ejecutar los segmentos de cdigo servlet y devolver una pgina HTML o imprimir un informe XML. Este capitulo modifica el fichero WAR del capitulo anterior para usar una pgina JSP en lugar de BonusServlet.

Crear la Pgina JSP


Una pgina JSP se parece a una pgina HTML con segmentos de cdigo servlet embebidos entre varias etiquetas de apertura ( <% ) y cierre (%> ) JSP. No hay mtodos HttpServlet como init , doGet, o doPost. En su lugar, el cdigo que normalmente ira en estos mtodos est directamente embebido en la pgina JSP usando etiequetas JSP. La siguiente pgina JAP ( Bonus.jsp ) es equivalente al BonusServlet del capitulo anterior. Despus del cdigo podremos ver una descripcin detallada de las etiquetas JSP. Observa que las etiquetas JSP no pueden estar anidadas. Por ejemplo, no podemos anidar una etiqueta de comentario JSP con una etiqueta scriptlet JSP. <HTML> <HEAD> <TITLE>Bonus Calculation</TITLE> </HEAD> <%-- Comment Scriptlet for import statements <%@ indicates a jsp directive --%> <%@ page import="javax.naming.*" %> <%@ page import="javax.rmi.PortableRemoteObject" %> <%@ page import="Beans.*" %> <%-- Comment Scriptlet to get the parameters, convert string to Integer to int for bonus calculation, and declare/initialize bonus variable. <% indicates a jsp scriptlet --%> <%! String strMult, socsec; %> <%! Integer integerMult; %> <%! int multiplier; %> <%! double bonus; %> <% strMult = request.getParameter("MULTIPLIER"); socsec = request.getParameter("SOCSEC"); integerMult = new Integer(strMult); multiplier = integerMult.intValue(); bonus = 100.00; %> <%-- Comment Scriptlet to look up session Bean --%> <% InitialContext ctx = new InitialContext();
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

51

Object objref = ctx.lookup("calcs"); CalcHome homecalc = (CalcHome) PortableRemoteObject.narrow( objref, CalcHome.class); %> <%-- Comment Scriptlet to create session Bean, call calcBonus method, and retrieve a database record by the social security number (primary key) --%> <% try { Calc theCalculation = homecalc.create(); Bonus theBonus = theCalculation.calcBonus( multiplier, bonus, socsec); Bonus record = theCalculation.getRecord(socsec); %> <%-- Comment HTML code to display retrieved data on returned HTML page. --%> <H1>Bonus Calculation</H1> Social security number retrieved: <%= record.getSocSec() %> <P> Bonus Amount retrieved: <%= record.getBonus() %> <P> <%-- Comment Scriptlet to catch DuplicateKeyException --%> <% } catch (javax.ejb.DuplicateKeyException e) { String message = e.getMessage(); %> <%-- Comment HTML code to display original data passed to JSP on returned HTML page --%> Social security number passed in: <%= socsec %> <P> Multiplier passed in: <%= strMult %> <P> Error: <%= message %> <%-- Comment Scriptlet to close try and catch block --%> <% } %> <%-- Comment HTML code to close HTML body and page --%> </BODY> </HTML>

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

52

Comentarios
Las primeras siete lneas de Bonus.jsp muestran un HTML normal seguido por un comentario JSP. Los comentarios JSP son similares a los comentarios HTML excepto en que empiezan con <%-- en lugar de <!--, que es como empiezan en HTML. Podemos usar comentarios JSP o HTML en una pgina HTML. Los comentarios HTML se envan al navegador web del cliente donde aparezcan como parte de la pgina HTML, y los comentarios JSP son eliminados y no aparecen en el HTML generado. Nota: Hemos visto que poner dos puntos (:) en un comentario JSP como en <%-- Comment: Scriptlet for import statements . . . creaba un error en tiempo de ejecucin que desapareca cuando eliminamos los dos puntos. <HTML> <HEAD> <TITLE>Bonus Calculation</TITLE> </HEAD> <%-- Comment Scriptlet for import statements <%@ indicates a jsp directive --%>

Directivas
Las directivas JSP son instrucciones procesadas por el motor JSP cuando la pgina JSP se traduce a un servlet. Las directivas usadas en este ejemplo le dicen al motor JSP que incluya ciertos paquetes y clases. Las directivas estn encerradas entre etiquetas de directiva <%@ y %>. <%@ page import="javax.naming.*" %> <%@ page import="javax.rmi.PortableRemoteObject" %> <%@ page import="Beans.*" %>

Declaraciones
Las declaraciones JSP nos permiten configurar variables para su uso posterior en expresiones o scriptlets. Tambin podemos declarar variables dentro de expresiones o scriptlets en el momento de usarlas. El mbito es toda la pgina JSP, no hay concepto de variables de ejemplar. Es decir, no tenemos que declarar variables de ejemplar para usar en ms de una expresin o scriptlet. Las declaraciones van encerradas entre etiquetas de declaracin <%! y %>. Podemos tener varias declaraciones. Por ejemplo, <%! double bonus; String text; %> . <%! String strMult, socsec; %> <%! Integer integerMult; %> <%! int multiplier; %> <%! double bonus; %>

Scriptlets
Los scriptlets JSP nos permiten embeber segmentos de cdigo java dentro de una pgina JSP. El codigo embebido se inserta directamente en el servlet generado que se ejecuta cuando se pide la pgina. Este scriptlet usa las variables declaradas en las directivas descritas arriba. Los Scriptlets van encerradas entre etiquetas <% y %>. <% strMult = request.getParameter("MULTIPLIER"); socsec = request.getParameter("SOCSEC"); integerMult = new Integer(strMult); multiplier = integerMult.intValue(); Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile 53

bonus = 100.00; %>

Variables Predefinidas
Un scriptlet puede usar las siguientes variables predefinidas: session, request, response, out , e in. Este ejemplo usa la variable predefinida request, que es un objeto HttpServletRequest. De igual forma, response es un objeto HttpServletResponse, out es un objeto PrintWriter, e in es un objeto BufferedReader. Las variables predefinidas se usan en los scriptlets de la misma forma que se usan en los servelts, excepto que no las declaramos. <% strMult = request.getParameter("MULTIPLIER"); socsec = request.getParameter("SOCSEC"); integerMult = new Integer(strMult); multiplier = integerMult.intValue(); bonus = 100.00; %>

Expresiones
La expresiones JSP nos permiten recuperar dinmicamente o calcular valores a insertar directamente en la pgina JSP. En este ejemplo, una expresin recupera el nmero de la seguridad social desde el bean de entidad Bonus y lo pone en la pgina JSP. <H1>Bonus Calculation</H1> Social security number retrieved: <%= record.getSocSec() %> <P> Bonus Amount retrieved: <%= record.getBonus() %> <P>

Etiquetas Especificas de JSP


La especificacin JavaServer Pages 1.1 define etiquetas especficas de JSP que nos permiten extender la implementacin JSP con nuevas caractersticas y ocultar mucha complejidad a los diseadores visuales que necesitan buscar la pgina JSP y modificarla. El ejemplo JSP de esta leccin no usa ninguna de estas etiquetas especficas, pero las veremos en la siguiente leccin. Las etiquetas especficas JSP definidas en la especificacin 1.1 son las siguientes: jsp:forward y jsp:include para instruir al motor JSP que pase de la pgina actual a otra pgina JSP. jsp:useBean, jsp:setProperty, jsp:getProperty nos permiten embeber y utilizar tecnologa JavaBeans en pginas JSP. jsp:plugin descarga automticamente el Plug-In Java al cliente para ejecutar applet en la plataforma Java adecuada.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

54

Modificar bonus.html
El nico cambio que necesitamos hacer a bonus.html es hacer que el parametro ACTION del formulario HTML invoque a Bonus.jsp en lugar de a BonusServlet . <HTML> <BODY BGCOLOR = "WHITE"> <BLOCKQUOTE> <H3>Bonus Calculation</H3> <FORM METHOD="GET" ACTION="Bonus.jsp"> <P> Enter social security Number: <P> <INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT> <P> Enter Multiplier: <P> <INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT> <P> <INPUT TYPE="SUBMIT" VALUE="Submit"> <INPUT TYPE="RESET"> </FORM> </FORM> </BLOCKQUOTE> </BODY> </HTML>

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 directorio 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
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

55

Eliminar el Fichero WAR


Como se ha aadido una pgina JSP al componente Web, tenemos que borrar el fichero WAR de las lecciones anteriores y crear uno nuevo con la pgina JSP. Local Applications: Pulsar el icono 2BeansApp para poder ver los componentes de nuestra aplicacin. Seleccionamos BonusWar para que se ilumine. Seleccionamos Delete desde el men Edit. Crear el Nuevo Fichero WAR Men File: Seleccionamos New Web Component Introduction: Leemos y pulsamos Next . War File General Properties : Nota: Parece que hay un bug en la herramienta Deploy. Debemos asegurarnos de aadir primero Bonus.jsp seguido de bonus.html. Si aadimos primero bonus.html, la herramienta Deploy pone bonus.html donde debera ir Bonus.jsp y Bonus.jsp donde debera ir bonus.html. Si esto sucede, podemos corregirlo manualmente copindolos en las localizaciones correctas. As es como deben estar despus del despliegue: ~/j2sdkee1.2/public_html/JSPRoot/bonus.html ~/j2sdkee1.2/public_html/JSPRoot/WEB-INF/classes/Bonus.jsp Especificamos BonusWar para el nombre de display. Pulsamos Add Vamos al directorio ClientCode y aadimos Bonus.jsp, Pulsamos Next Vamos al directorio ClientCode y aadimos bonus.html Pulsamos Finish . Propiedades Generales del Fichero War : Pulsamos Next. Elegir el tipo de Componente: . Seleccionamos Describe a JSP. Pulsamos Next. Propiedades generales del Componente: Ponemos Bonus.jsp como nombre de fichero JSP. Ponemos BonusJSP como nombre de display. Pulsamos Finish . Ventana Inspecting: Seleccionamos Web Context Especificamos JSPRoot.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

56

Verificar y Desplegar la Aplicacin J2EE


Antes de desplegar la aplicacin, es una buena idea ejecutar el verificador. El verificador mostrar los errores en los componentes de la aplicacin como mtodos inexistentes que el compilador no captura. Verificar: Con 2BeansApp seleccionado, elegimos Verifier desde el men Tools. En el dilogo que aparece, pulsamos OK. La ventana debera decir que no hay ningn fallo. Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicacin.

Nota: En la versin 1.2.1 del software podramos obtener un error tests app.WebURI. Esto significa que la herramienta DeployTool no puso la extensin .war al fichero WAR durante su creaccin. Es un error menor y la aplicacin J2EE se despliega sin problemas. Desplegar: Desde el men Tools, elegimos Deploy Application. Se mostrar una caja de dilogo Deploy BonusApp. Verificar que la seleccin 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 aplicacin solitaria para el programa cliente. Este ejemplo usa un servlet y una pgina HTML por lo que no debe estr marcada. Esta caja crea un fichero JAR con toda la informacin de despliegue necesaria para una aplicacin 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 JSPRoot. 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 dilogo que mostrar el estado de la operacin de despliegue. Cuando se haya completado, las tres barras de la izquierda se habrn sombreado completamente, como se ve en la siguiente figura. Cuando esto suceda pulsamos OK.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

57

Ejecutar la Aplicacin J2EE


El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la pgina bonus.html apuntamos nuestro navegador a http://localhost:8000/JSPRoot/bonus.html, que es dnde la herramienta de despliegue puso el fichero HTML. Nota: La Herramienta Deploy pone Bonus.jsp bajo public_html/JSPRoot , y bonus.html bajo public_html/JSPRoot/WEB-INF/classes, que es lo opuesto a donde realmente pertenecen. Manualmente los copiamos en sus localizaciones correctas como sigue public_html/JSPRoot/bonus.html y public_html/JSPRoot/WEBINF/classes/Bonus.jsp. Rellenamos un nmero de la seguridad social y un multiplicador. Pulsamos el botn Submit. Bonus.jsp procesa nuestros datos y devuelve una pgina HTML con el bono calculado. Bonus Calculation Social Security number retrieved: 777777777 Bonus Amount Retrieved: 200.0 Si hemos suministrado dos veces el mismo nmero de la seguridad social, veremos algo similar a esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Error: Duplicate primary key

Capitulo V - Tecnologa JavaBeans


Podemos usar la tecnologa JavaBeans para poner un JavaBean entre una pgina JSP y el bean de sesin CalcBean para obtener una mejor separacin "Model, View, Controller (MVC)". MVC es un patrn de diseo que consiste en tres tipos
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

58

de objetos. El Modelo proporciona la lgica de negocio de la aplicacn, la Vista es la presentacin en pantalla, y el Controlador es un objeto que maneja lo que sucede cuando el usuario interacta con la Vista. Un patrn de diseo describe un problema recurrente y sus soluciones cuando la solucin no es siempre exactamente la misma para cada recurrencia. La leccin sobre Tecnologa JSP se configur para que las pginas HTML y JSP proporcionaran la presentacin en pantalla (Vista) y manejar lo que sucedia cuando el usuario interacta con los datos (Controlador). Los beans de entidad y de sesin ( BonusBean y CalcBean ) son los objetos de la aplicacin o Modelo. Esta leccin usa una pgina JSP para la presentacin en pantalla (View), un JavaBean para manejar lo que sucede cuando el usuario interacta con la vista (Controlador), y los beans de entidad y de sesin para los objetos de aplicacin (Modelo). Separando el Controlador de la Vista permite al JavaBean servir como una envoltura para el bean de sesin y ofrece un ejemplo mucho ms claro de la separacin MVC. Una aplicacin que usa patrones de diseo es mucho ms sencilla de actualizar, mantener y manejar.

Sobre el Ejemplo
En la Leccin anterior, el interface de usuario de la aplicacin consiste en una pgina HTML con un formulario HTML. El formulario llama a la pgina JSP cuando el usuario pulsa el botn Submit de la pgina HTML. Otra forma de crear el interface de usuario es con una pgina JSP que incluya el formulario HTML, scriptlets JSP, y etiquetas especficas JSP para interactar con el JavaBean. Cuando se carga la pgina JSP, se muestra el formulario HTML y se ejecutan los escriptlets y las etiquetas especificas JSP para interactuar con el JavaBean. Como todava no se han suministrado datos, la pantalla se parecer a la de la siguiente figura

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

59

Cuando el usuario introduce algn dato y pulsa el botn Submit, se vuelve a mostrar el formulario HTML, y se ejecutan de

nuevo los scriptlets y las etiquetas especificas JSP con los datos suministrados. La pantalla se parecera algo a la de la siguiente figura. Esto es porque el parmetro ACTION del formulario HTML de bonus.jsp se llama a s mismo de forma recursiva. Si el usuario introduce el mismo nmero de la seguridad social, se devuelve un error de clave duplicada y se muestra sobre la pgina JSP como se muestra en la siguiente figura:

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

60

Crear bonus.jsp
El cdigo de bonus.jsp es bastante sencillo poque el cdigo que busca el bean de sesin y calcula el bono est ahora en el JavaBean. La primera parte del fichero contiene el cdigo HTML para crear el formulario. El cdigo para pasar los datos del formulario HTML al JavaBean est en la segunda parte del fichero. Abajo podemos ver el fichero bonus.jsp completo: <HTML> <BODY BGCOLOR = "WHITE"> <HEAD> <TITLE>Bonus Calculation</TITLE> </HEAD> <BLOCKQUOTE> <H3>Bonus Calculation</H3> <!--ACTION parameter calls this page--> <FORM METHOD="GET" ACTION="bonus.jsp"> <P> Enter social security Number: <P> <INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT> <P> Enter Multiplier: <P> <INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT> <P> <INPUT TYPE="SUBMIT" VALUE="Submit"> <INPUT TYPE="RESET"> </FORM> <!--Scriptlet and JavaBeans Tags start here --> <jsp:useBean id = "jbonus" class = "JBonusBean"/> <%! String sMult, ssec; %> <% sMult = request.getParameter("MULTIPLIER"); ssec = request.getParameter("SOCSEC"); %> <jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/> <jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/> Social security number retrieved: <jsp:getProperty name="jbonus" property="socsec"/>

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

61

<P> Bonus Amount retrieved: <jsp:getProperty name="jbonus" property="bonusAmt"/> <P> Error messages: <jsp:getProperty name = "jbonus" property="message"/> </BLOCKQUOTE> </BODY> </HTML>

Especificar el JavaBean
La siguiente etiqueta HTML especifica el JavaBean que se esta utilizando en este ejemplo. El parmetro id define un alias para usarlo como referencia al JavaBean, y el parmetro class especifica la clase JavaBean. En este ejemplo el id es jbonus y el class es JBonusBean. <jsp:useBean id = "jbonus" class = "JBonusBean"/>

Obtener los Datos


Los siguientes scriptlets JSP recuperan los datos suministrados por el usuario desde los campos del formulario HTML. El multiplicador se almacena en la variable sMult String, y el nmero de la seguridad social en la variable ssec String. <%! String sMult, ssec; %> <% sMult = request.getParameter("MULTIPLIER"); ssec = request.getParameter("SOCSEC"); %>

Pasar los Datos al JavaBean


Las siguientes etiquetas HTML configuran dos propiedades del JavaBean. Una propiedad es un campo privado de la clase JavaBean. La primera lnea usa la etiqueta jsp:setProperty para configurar el campo strMult en la clase JBonusBean (con el alias jbonus id) al valor almacenado en la variable sMult. La segunda lnea realiza una operacin similar para el campo socsec de la clase JBonusBean. <jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/> <jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/> La expresin value="<%=ssec%>" enva el dato contenido en la variable ssec al campo socsec del JavaBean.

Recuperar los Datos desde el JavaBean


Recuperar los datos desde el JavaBean es similar a envirselos. Usamos la etiqueta jsp:getProperty e indicamos la propiedad (campo privado) cuyo dato queremos obtener. La siguiente etiqueta getProperty obtiene el dato almacenado en el campo privado socsec de la clase JBonusBean (con el alias jbonus id ). Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile 62

Social security number retrieved: <jsp:getProperty name="jbonus" property="socsec"/> Las siguientes etiquetas realizan operaciones similares para los campos bonusAmt y message de la clase JBonusBean. <P> Bonus Amount retrieved: <jsp:getProperty name="jbonus" property="bonusAmt"/> <P> Error messages: <jsp:getProperty name = "jbonus" property="message"/>

Crear la Clase JavaBean


Una clase JavaBeans (o bean para acortar) se parece a cualquier clase normal del lenguaje Java. Pero para ser un bean, una clase JavaBean debe seguir un conjunto de sencillas convenciones de nombres y diseo explicados en la especificacin JavaBeans. Como los Beans cumplen la especifiacin JavaBean, pueden ser accedidos y manejados por otros programas y herramientas que cumplan las mismas convenciones. En la seccin Crear bonus.jsp, se utilizarn etiquetas HTML y scriptlets JSP para obtener y seleccionar los datos privados de la clase JBonusBean. Esto es posible porque la clase JBonusBean sigue las convenciones de nombrado y diseo de JavaBeans. Esta seccin describe el cdigo de JBonusBean y nos ofrece una sencilla presentacin de la tecnologa JavaBeans cuando se usa con pginas JSP. Aqu tenemos la clase JBonusBean completa. import javax.naming.*; import javax.rmi.PortableRemoteObject; import Beans.*; public class JBonusBean { private String strMult, socsec, message; private double bonusAmt; CalcHome homecalc; public JBonusBean() { try{ InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("calcs"); homecalc = (CalcHome) PortableRemoteObject.narrow( objref, CalcHome.class); } catch (javax.naming.NamingException e) { e.printStackTrace(); } } public double getBonusAmt() { if(strMult != null){ Integer integerMult = new Integer(strMult);
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

63

int multiplier = integerMult.intValue(); try { double bonus = 100.00; Calc theCalculation = homecalc.create(); Bonus theBonus = theCalculation.calcBonus( multiplier, bonus, socsec); Bonus record = theCalculation.getRecord( socsec); bonusAmt = record.getBonus(); socsec = record.getSocSec(); } catch (javax.ejb.DuplicateKeyException e) { message = e.getMessage(); } catch (javax.ejb.CreateException e) { e.printStackTrace(); } catch (java.rmi.RemoteException e) { e.printStackTrace(); } return this.bonusAmt; } else { this.bonusAmt = 0; this.message = "None."; return this.bonusAmt; } } public String getMessage(){ return this.message; } public String getSocsec(){ return this.socsec; } public String getStrMult(){ return this.strMult; } public void setSocsec(String socsec) { this.socsec = socsec; } public void setStrMult(String strMult) { this.strMult = strMult; } }

Propiedades del Bean


Las propiedades definen los datos que un JavaBean pone a disposicin de otros programas o herramientas a travs de mtodos get o set. Los datos podran hacer cosas como definir la apariencia o el comportamiento del JavaBean, o utilizarse para algn clculo, etc. Las propiedades realmente son campos privados de la clase que siempre deberan ser privados y slo accesibles a travs de mtodos set y get.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

64

El siguiente segmento de cdigo muestra las propiedades privadas de la clase JBonusBean. Esta clase tiene un correspondiente mtodo get<property> para cada campo y sus correspondientes mtodos set<property> para los campos strMult y socsec. public class JBonusBean { private String strMult, socsec, message; private double bonusAmt;

Constructor
El constructor JBonusBean busca el bean de sesin. public JBonusBean() { try{ InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("calcs"); homecalc = (CalcHome) PortableRemoteObject.narrow( objref, CalcHome.class); } catch (javax.naming.NamingException e) { e.printStackTrace(); } }

Mtodos Set
JBonusBean tiene dos mtodos set (mtodos precedidos por la palabra set). Estos mtodos seleccionan propiedades (campos privados) con valores especificados. Los dos mtodos set son setSocsec y setStrMult para seleccionar los campos privados socsec y strMult (propiedades JavaBean) . En este ejemplo, los valores usados para las propiedades socsec y strMult vienen de las etiquetas setProperty name de la pgina JSP. El servidor J2EE usa la informacin suministrada en la siguiente etiqueta setProperty name para localizar el correspondiente mtodo set en JBonusBean (con el alias jbonus id ): <jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/> <jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/> En la clase JBonusBean, los mtodos set<property> siguen las convenciones de nombrado para que el servidor J2EE pueda mapear las etiquetas setProperty name del fichero JSP a los mtodos set<property> correctos para pasar los datos desde la pgina JSP al JavaBean. Con los mtodos set, el nombre de mtodo consiste en la palabra set y el nombre de la propiedad. El nombre de la propiedad es el nombre de uno de los campos privados de JBonusBean. Mientras que los nombres de campos por convencin empiezan siempre con una letra minscula, la segunda palabra de un nombre de mtodo siempre empieza con una myuscula. Por eso, para seleccionar el campo privado socsec, el nombre del mtodo es setSocsec. El servidor J2EE mapea la mayscula de Socsec en el nombre del mtodo a la minscula socsec del campo. Los mtodos set no tienen valor de retorno y tienen un argumento del tipo apropiado. public void setSocsec(String socsec) { this.socsec = socsec;
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

65

} public void setStrMult(String strMult) { this.strMult = strMult; }

Mtodos Get
JBonusBean tiene cuatro mtodos get (mtodos precedidos por la palabra get ). Los mtodos Get obtienen y devuelven un valor de propiedad (valores de campos privados). Los cuatro mtodos get son getBonusAmt, getMessage, getSocsec, y getStrMult para devolver datos desde los campos privados bonusAmt, message , socsec , y strMult (propiedades JavaBean). En este ejemplo, los valores usados para seleccionar los campos bonusAmt y message vienen desde el mtodo getBonusAmt. La pgina JSP recupera los datos de las propiedades de JBonusBean usando las siguientes etiquetas getProperty name. La pgina JSP slo recupera los valores que le interesan, por eso podramos observar que aunque hay una propiedad en JBonusBean para el multiplicador (el campo strMult), este valor no es recuperado por la pgina JSP. Social security number retrieved: <jsp:getProperty name="jbonus" property="socsec"/> <P> Bonus Amount retrieved: <jsp:getProperty name="jbonus" property="bonusAmt"/> <P> Error messages: <jsp:getProperty name = "jbonus" property="message"/> Los mtodos Get siguen las mismas convenciones de nombres que los mtodos Set por eso la pgina JSP puede recuperar los datos del JBonusBean. Los mtodos Get siempre tienen un valor de retorno y no tienen argumentos. Podramos observar que aunque el mtodo getBonusAmt seleccciona valores de propiedades, realmente no necesita devolver ningn valor en este ejemplo, devuelve this.bonusAmt para evitar un error en tiempo de ejecucin del servidor J2EE. El mtodo getBonusAmt usa una sentencia if-else para manejar el caso cuando no se suministra ningn valor strMult. Cuando la pgina JSP se carga por primera vez, el usuario final no ha suministrado ningn dato, pero todas las etiquetas y scriptlets de la pgina son ejecutados de cualquier forma. En este caso, el valor de la propiedad strMult pasada a JBonusBean es null, lo que resulta en un multiplicador nulo y un valor nulo de bonusAmt. Ocurre un error de servidor cuando la pgina JSP obtiene e intenta mostrar el valor null de bonusAmt. Para evitar este error, bonusAmt se selecciona a cero en el caso de que se reciba un valor null desde la pgina JSP. public double getBonusAmt() { if(strMult != null){ Integer integerMult = new Integer(strMult); int multiplier = integerMult.intValue(); try { double bonus = 100.00; Calc theCalculation = homecalc.create(); Bonus theBonus = theCalculation.calcBonus( multiplier, bonus, socsec); Bonus record = theCalculation.getRecord(
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

66

socsec); bonusAmt = record.getBonus(); socsec = record.getSocSec(); } catch (javax.ejb.DuplicateKeyException e) { message = e.getMessage(); } catch (javax.ejb.CreateException e) { e.printStackTrace(); } catch (java.rmi.RemoteException e) { e.printStackTrace(); } return this.bonusAmt; } else { this.bonusAmt = 0; this.message = "None."; return this.bonusAmt; } } public String getMessage(){ return this.message; } public String getSocsec(){ return this.socsec; } public String getStrMult(){ return this.strMult; } public void setSocsec(String socsec) { this.socsec = socsec; } public void setStrMult(String strMult) { this.strMult = strMult; }

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 directorio 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
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

67

j2sdkee1.2.1\bin\cloudscape -start

Eliminar el Fichero WAR


Como se ha aadido una pgina JSP al componente Web, tenemos que borrar el fichero WAR de las lecciones anteriores y crear uno nuevo con la pgina JSP. Local Applications: Pulsar el icono 2BeansApp para poder ver los componentes de nuestra aplicacin. Seleccionamos BonusWar para que se ilumine. Seleccionamos Delete desde el men Edit.

Crear el Nuevo Fichero WAR


Men File: Seleccionamos New Web Component Introduction: Leemos y pulsamos Next . War File General Properties : Especificamos BonusWar para el nombre de display. Pulsamos Add Vamos al directorio ClientCode y aadimos Bonus.jsp, Pulsamos Next Vamos al directorio ClientCode y aadimos JBonusBean.class Pulsamos Finish . Propiedades Generales del Fichero War : Pulsamos Next. Elegir el tipo de Componente: . Seleccionamos Describe a JSP. Pulsamos Next. Propiedades generales del Componente: Ponemos Bonus.jsp como nombre de fichero JSP. Ponemos BonusJSP como nombre de display. Pulsamos Finish . Ventana Inspecting: Seleccionamos Web Context Especificamos JSPRoot.

Verificar y Desplegar la Aplicacin J2EE


Antes de desplegar la aplicacin, es una buena idea ejecutar el verificador. El verificador mostrar los errores en los componentes de la aplicacin como mtodos inexistentes que el compilador no captura. Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile 68

Verificar: Con 2BeansApp seleccionado, elegimos Verifier desde el men Tools. En el dilogo que aparece, pulsamos OK. La ventana debera decir que no hay ningn fallo. Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicacin.

Nota: En la versin 1.2.1 del software podramos obtener un error tests app.WebURI. Esto significa que la herramienta DeployTool no puso la extensin .war al fichero WAR durante su creaccin. Es un error menor y la aplicacin J2EE se despliega sin problemas. Desplegar: Desde el men Tools, elegimos Deploy Application. Se mostrar una caja de dilogo Deploy BonusApp. Verificar que la seleccin 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 aplicacin solitaria para el programa cliente. Este ejemplo usa un servlet y una pgina HTML por lo que no debe estr marcada. Esta caja crea un fichero JAR con toda la informacin de despliegue necesaria para una aplicacin 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 JSPRoot. 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 dilogo que mostrar el estado de la operacin de despliegue. Cuando se haya completado, las tres barras de la izquierda se habrn sombreado completamente, como se ve en la siguiente figura. Cuando esto suceda pulsamos OK.

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

69

Ejecutar la Aplicacin J2EE


El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la pgina bonus.html apuntamos nuestro navegador a http://localhost:8000/JSPRoot/bonus.html, que es dnde la herramienta de despliegue puso el fichero HTML. Rellenamos un nmero de la seguridad social y un multiplicador. Pulsamos el botn Submit. Bonus.jsp procesa nuestros datos y devuelve una pgina HTML con el bono calculado.

Bonus Calculation Social Security number retrieved: 777777777 Bonus Amount Retrieved: 200.0 Si hemos suministrado dos veces el mismo nmero de la seguridad social, veremos algo similar a esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Error: Duplicate primary key

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

70

Capitulo VI - Aadir eXtensible Markup Language (XML)


eXtensible Markup Language (XML) es un lenguaje para representar y describir datos basados en texto para que los datos puedan ser ledos y manejados por cualquier programa o herramienta que use los APIs XML. Los programas y herramientas pueden generar ficheros XML que otros programas y herramientas pueden leer y manejar. Por ejemplo, una compaa puede usar XML para producir informes para que las diferentes partes que reciban los informes puedan manejar los datos de una forma apropiada a sus necesidades. Una parte podra pasar los datos XML a travs de un programa para traducirlos a HTML y poder ponerlos en la Web, otra parte podra pasar los datos por una herramienta para producir un inform de stocks, y otra tercera parte podra pasar los datos XML a travs de una herramienta para crear una presentacin de marketing. Mismos datos, diferentes necesidades, y un grupo de programas y herramientas independientes de la plataforma para usar los mismos datos en varis formas distintas. Estas capaciades tan flexibles y baratas estn disponibles a travs de etiquetas XML, Definiciones de Tipos de Documentos (DTDs) tambin conocidos com esquemas XML, y los APIs XML. Esta leccin adapta el ejemplo de la Leccin anterior para que la clase JavaBeans use los APIs XML para impriir un sencillo informe donde los datos estn marcados con etiquetas XML.

Marcar y Manejar Texto


Con XML definimos etiquetas de marcas para representar diferentes elementos de datos en un fichero de texto. Por ejemplo, si tenemos un fichero de texto que consiste en un pequeo artculo, definimos etiquets que represente el ttulo, el autor, las cabeceras de primer nivel, las cabeceras de segundo nivel, las listas bulleteadas, el texto del artculo, etc. Una vez que los datos estn representados por etiquetas XML, podemos crear una Definicin de Tipo de Documento (DTD) y/o un fichero "eXtensible Style sheet Language (XSL)" para describir cmo queremos que se manejen los datos. Los estilos XSL nos pemiten hacer cosas como el mapeo de XML a HTML. Por ejemplo, podemos definir una etiqueta de ttulo XML para que represente el ttulo de un artculo, y crear un fichero XSL que mapee la etiqueta de ttulo CML a una etiqueta H1 de HTML para mostrarselo al usuario final. Un DTD (tambin conocido como esquema XML) contiene especificaciones que permiten a otros programa validad la estructura de un fichero XML para asegurarse que los datos estn etiquetados de la forma correcta. Por ejemplo, un DTD para un artculo podra permitir una etiqueta de ttulo, pero cero o ms primeros y segundos niveles de cabeceras.

Cualquier programa capaz de analizar XML puede chequear etiquetas XML bien-formadas, y cualquier programa capaz de aplicar estilos XLS o especificaciones DTD a datos XML puede manejar datos que fueron etiquetados de forma inteligente. Por ejemplo, si un artculo titne dos etiquetas de ttulo, pero el DTD permite slo una, el programa devuelve un error. Chequear un documento XML contra un DTD es lo que se conoce como verificacin. Lo ms bonito sobre XML es que el etiquetado est separado de las hojas de estilos y DTD. Esto significa que podemos tener un documento XML y desde a muchas hojas de estilo o DTDs. Diferentes hojas de estilo nos permiten tener

diferentes presentaciones dependiendo de cmo se utilice el documento. Por ejemplo, un artculo en XML puede tener una hoja de estilo para diferentes web sites donde se va a publicar para que corresponda con el aspecto y comportamietno de cada site. Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile 71

La versin actual de J2EE no tiene un motor de "eXtensible Style sheet Language Transformation (XSLT)" por eso no es posible actualmente usar una hoja de estilo para hacer cosas como transformar un documento XML en HTML para mostrarlo.

Modificar la Clase JavaBean


En esta leccin, se aade un mtodo genXML a la clase JBonusBean para generar el documento XML mostrado abajo. Despus de ver las etiquetas y estructura de un documento XML vermos el cdigo que genera este documento XML. <?xml version="1.0"?> <report> <bonusCalc ssnum="777777777" bonusAmt="300.0" /> </report>

Prlogo XML
La lnea <?xml version="1.0"?> es el prlogo XML. Un fichero XML siempre debe empezar con un prologo que lo identifique como un fichero XML. El prlo no es necesario si slo va a ser ledo por humanos, pero es buena idea incluirlo. Junto con la informacin de versin, el prlogo tambin puede incluir informacin de codificacin e informacin "standalone . Informacin de Codificacin: indica el conjunto de caracteres usado en los datos del documento. Unicode descomprimido se representa como <?xml version="1.0" encoding="UTF-8"?>. El conjunto de caracteres Western European y lenguaje Ingls se indica como: <?xml version="1.0" encoding="ISO8859-1"?>. Informacin Standalone: idnica si este documento usa informacin de otros ficheros. Por ejemplo, un documento XML podra relacionarse con una hoja de estilo para infomacin sobre cmo crear un interface de usuario e HTML, o un DTD para especificaciones de etiquetas vlidas.

Documento Raz
La etiqueta <report> es la primera etiqueta XML de este fichero. Es la etiqueta XML de ms alto nivel y marca el inicio de los datos del documento. Otro nombre para este nivel de etiqueta es root. Las etiquetas XML tienen su correspondiente etiqueta final, por eso el final de este documento tiene su correspondiente etiqueta </report> para cerrar la pareja. Podemos darle a una etiqueta XML cualquier nombre que queramos. Este ejemplo usa report porque el fichero XML es un informe de bonos. Podra haberse llamado <root> o <begin> o cualquier otra cosa. el nombre tiene significado en la hoja de estilo y en el DTD porque es donde asignamos especificaciones para las etiquetas por sus nombres.

Nodos Hijos
La etiqueta <bonusCalc> representa el informe de bonos. Esta etiqueta es un nodo hijo que se aade al raz. Usa atributos para especificar el nmero de la seguridad social y el valor del bono ( ssnum y bonusAmt ). Podemos definir un DTD para chequear que las etiquetas bonusCalc tienen los atributos ssnum y bonusAmt, y poder hacer que nuestro programa corriga un error si ha desaparecido algn atributo o si los atributos presentes no deberian estar ah. <bonusCalc ssnum="777777777" bonusAmt="300.0" />
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

72

Otras Etiquetas XML


Hay varias formas de etiquetar datos XML. Este ejemplo usa etiquetas vacas, que son etiquetas que no encierran datos, usan atributos para especificar datos, y se cierran con una barra inclinada. La siguiente etiqueta vaca de este ejemplo, podra crearse para que los datos se encerraran entre etiquetas XML. El analizador XML chequea todos los datos encerrados por datos que llamados etiquetas bien-formadas. Las etiquetas bien-formadas consisten en una etiqueta de apertura y una de cierre como es muestra en el ejemplo de abajo: Etiqueta Vaca: <bonusCalc ssnum="777777777" bonusAmt="300.0" /> Etiquetas bien-formadas: <bonusCalc> <ssnum>"777777777"</ssnum> <bonusAmt>300.0</bonusAmt> </bonusCalc> Los comentarios XML son como las etiquetas de comentario HTML. <!-- Bonus Report --> <bonusCalc ssnum="777777777" bonusAmt="300.0" /> Las instrucciones de procesamiento le dan comandos o informacin a una aplicacin que est procesando los datos XML. Las instrucciones de procesamiento tienen el formado <? target instructions?> donde target es el nombre de la aplicacin que est haciendo el procesamient, e instructions encierra la informacin o comandos para que los procese la aplicacin. El prlogo es un ejemplo de una instruccin de procesamiento, donde xml es la fuente y version="1.0" encierra las instrucciones. Debemos observar que el nombre de fuente xml esta reservado para estndar XML. <?xml version="1.0"?> Tambin podemos usar instrucciones de procesamiento par ahacer cosas como distinguir entre diferentes versiones de una representacin como la versin de alto nivel ejecutivo y la versin de nivel tcnico.

Cdigo del JavaBean


La clase JBonusBean para esta leccin tiene sentencias import para crear el documento XML, manejar errores, y escribir el documento en el terminal. Esta leccin escribe la salida del XML en el terminal para mantener las cosas sencillas. Tambin podra escribirse en un fichero, pero necesitaramos configutrar nuestro navegador para usar el Java Plug-In e incluir un fichero de polica de seguridad que concediera permiso para escribir un fichero. Para generar el fichero XML para esta leccin, necesitamos importar las clases ElementNode y XmlDocument. Tambin necesitamos las clases StringWriter e IOException para escribir datos XML en el terminal. import import import import import import javax.naming.*; javax.rmi.PortableRemoteObject; Beans.*; java.io.StringWriter; java.io.IOException; com.sun.xml.tree.ElementNode; 73

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

import com.sun.xml.tree.XmlDocument; Esta versin de la clase JBonusBean tiene una variable ms de ejemplar. El interface remoto del bean de sesin, theCalculation, necesita ser accedido desde los mtodos getBonusAmt y genXML. Esto es porque genXML lee la base de datos para generar XML para todos los registros almacenados ene lla y tiene que poder acceder al mtodo getRecord del bean de sesin. Calc theCalculation; El mtodo JBonusBean.genXML es llamado desde el mtodo getBonusAmt despus de que el proceso se complete en el evento strMult y no sea null . Lo prmero que este mtodo hace es crear un objeto XMLDocument y el nodo raz, y aade la raz al documento. El nodo raz represetna el punto de ms alto nivel en el rbol del documento y es el punto donde empieza el procesamiento. private void genXML(){ Bonus records = null; //Create XML document XmlDocument doc = new XmlDocument(); //Create node ElementNode root = (ElementNode) doc.createElement("report"); //Add node to XML document doc.appendChild(root); Los bloques try y catch que vienen luego, obtienen el registro de la base de datos, recuperar el valor del bono y el nmero de la seguridad social desde el registro, convierte el valor del bono a un string, crea un nodo hijo ( bonusCalc ), y aade el nmero de la seguridad social y el bono al nodo hijo bonusCalc como atributos. El nodo hijo epresenta la herencia o rbol, y los atributos representan el tercer nivel. try{ //Get database record records = theCalculation.getRecord(socsec); //Retrieve the social security number from record String ssRetrieved = records.getSocSec(); //Retrieve bonus amount from record double bRetrieved = records.getBonus(); //Convert double to string Double bonusObj = new Double(bRetrieved); String bString = bonusObj.toString(); //Create child node ElementNode bonusCalc = (ElementNode) doc.createElement("bonusCalc"); //Add attributes to child node bonusCalc.setAttribute("ssnum", ssRetrieved); bonusCalc.setAttribute("bonusAmt", bString);

//Add child node to root root.appendChild(bonusCalc); } catch (java.rmi.RemoteException e) { e.printStackTrace(); }


Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

74

La ltima parte del mtodo genXML crea un objeto StringWriter, escribe la herencia del documento o rbol al objeto StringWriter, y escribe el objeto StringWriter al terminal. try{ StringWriter out = new StringWriter(); doc.write(out); System.out.println(out); } catch (java.io.FileNotFoundException fe) { System.out.println("Cannot write XML"); } catch (IOException ioe) { System.out.println("cannot write XML"); } El rbol o estructura del documento XML se llama Document Object Model (DOM). La siguiente figura muestra una representacin simplificada del DOM del ejemplo de esta leccin. Las llamadas al API en el mtodo genXML crea el DOM y podemos aplicar las llamadas al API para acceder al DOM paa hacer cosas como aadir, borrar y editar nodos hijos, o validar el DOM contra un DTD. Podemos crear un DOM desde un fichero XML.

Los APIs
El fichero j2ee.jar que viene con nuestra instalacin J2EE proporciona APIs para analizar y manipular datos XML. El fichero JAR realmente prporciona APIs XML para SAX, DOM y J2EE. Podemos usar cuaquier API que necesitamos como se muestra en la siguiente figura, el texto XML es independiente de la plataforma y el lenguaje de creaccin...

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

75

SAX y DOM
El API SAX es un mecanismo de acceso serial dirigido por eventos que hace un proceso elemento por elemento. El API DOM proporciona una estructura de objetos del tipo rbol relativamente familiar. Podemos usar el API DOM para manipular la herencia de los objetos que encapsula. El API DOM es ideal para aplicaciones interactivas porque el modelo completo del objeto est presente en la memoria, donde el usuario puede acceder a l y modificarlo. Construir el DOM requiere la lectura de la estructura XML completa y mantener el rbol de objetos en memoria, lo que significa mucho consumo de CPU y de memoria. Por esta razn, se tiende a preferir el API SAX para aplicaciones clienteservidor y para filtros de datos que no requieren una representacin de los datos en memoria.

J2EE
El API XML J2EE independiente de la plataforma usa un rbol DOM y proporciona muchos mtodos para manipularlo. los APIs XML J2EE estn en el paquete com.sun y se han utilizado en el ejemplo de esta leccin. No olvidemos que estos APIs estn sujetos a modificaciones.

Actualizar y Ejecutar la Aplicacin


Como todo lo que hemos hecho en esta leccin ha sido modificar la clase JBonusBean, simplementen podemos actualizar y redesplegar la aplicacin. Ventana Local Applicatons: Seleccionamos la aplicacin 2BeansApp. Men Tools: Seleccionamos Update and Redeploy Application.

Nota: La aplicacin BonusApp de la leccin anterior se desinstala automticamente. El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la pgina bonus.jsp apuntamos el navegador a http://localhost:8000/JSPRoot/bonus.jsp, que es donde la herramietna Deploy puso la pgina JSP. Rellenamos un nmero de la seguridad social y un multiplicador. Pulsamos el botn Submit. Bonus.jsp procesa nuestros datos y devuelve una pgina HTML con el bono calculado.

Capitulo VII - JDBC


Hasta ahora, la aplicacin de ejemplo J2EE ha escrito y ledo los datos desde una base de datos Cloudscape subyancente sin que hayamos escrito cdigo SQL. Esto es porque el contenedor ha estado manejando el almacenamiento y recuperacin de los datos a travs del bean de entidad. La persistencia controlada por el contenedor es el termino usado para describir la situacin donde el contenedor maneja el almacenamiento y la recuperacin. Esta leccin nos muestra como sobreescribir la persistencia controlada por el contenedor por defecto e implementar la persistencia controlada por el bean.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

76

La persistencia controlada por el bean es cuando nosotros escribimos mtodos de los beans de entidad o de sesin para usar los comandos SQL que le proporcionamos. La peristencia controlada por el bean puede ser util si necesitamos mejorar el rendimiento o mapear datos de varios beans en un fila de una tabla de base de datos. Esta leccin modifica el bean de entidad de la aplicacin de ejemplo J2EE para usar persistencia controlada por el bean.

Ciclo de Vida del Bean


La Leccin 3 mostraba la clase BonusBean manejada por el contenedor. Los nicos mtodos con implementaciones eran getBonus para devolver el valor del bono, getSocSec para devolver el nmero de la seguridad social, y ejbCreate para crear un bean de entidad y pasarle los valores bonus y socsec. El contenedor tena en cuenta cosas como la creaccin de la fila en la tabla de la base de datos, y asegurarse de que los datos en memoria era consistentes con los datos de la fila de la tabla. Con la persistencia controlada por el bean nosotros tenemos que implementar todos estos comportamientos, lo que significa aadir codigo JDBC y SQL, e implementar los mtodos vacos del ejemplo controlado por el contenedor. Un bean de sesin o de entidad consiste en mtodos de negocio y mtodos de ciclo de vida. en el ejemplo, CalcBean tiene dos mtodos de negocio, calcBean y getRecord , y BonusBean tiene dos mtodos de negocio getBonus y getSocsec. Tanto CalcBean como BonusBean tienen los siguientes mtodos de ciclo de vida. A los mtodos de negocio los llama el cliente y a los mtodos del ciclo de vida los llama el contenedor del bean. setEntityContext: El contenedor llama primero a este mtodo para pasar un objeto contexto al bean de entidad. El contexto de entidad lo actualiza dinamicamente el contenedor incluso si muchos clientes llaman al bean de entidad a la vez, el contexto contiene datos actuales para cada llamada. Un bean de sesin tiene un mtodo setSessionContext correspondiente que realiza una funcin similar a la del mtodo setEntityContext. ejbCreate: El contenedor llama a este mtodo cuando un cliente llama al mtodo create del interface home del bean. Por cada mtodo create en el interface home, el bean tiene un mtodo ejbCreate correspondiente con la misma firma (parmetros y valor de retorno). ejbPostCreate: El contenedor llama a este mtodo despus de que se complete el mtodo ejbCreate. Hay un mtodo ejbPostCreate por cada mtodo ejbCreate que toma los mismos argumentos que su mtodo create. Sin embargo, ejbPostCreate no tiene valor de retorno. Usamos ejbPostCreate para implementar cualquier procesamiento especial que necesitemos hacer despus de crear el bean y antes de que est disponible para el cliente. Lo podemos dejar en blanco si no necesitamos procesamiento especial. ejbRemove: El contenedor llama a este mtodo cuando un cliente llama al mtodo remove del interface home del bean. La aplicacin de ejemplo J2EE para este tutorial no incluye ningn mtodo remove en el interface home. unsetEntityContext: El contenedor llama a este mtodo despus de que se haya llamado a ejbRemove para eliminar el bean de entidad. Slo los beans de entidad tienen un mtodo unsetEntityContext. Un bean de sesin no tiene el correspondiente mtodo unsetSessionContext. ejbFindByPrimaryKey: El contenedor llama a este mtodo cuando un cliente llama al mtodo findByPrimaryKey del interface home del bean. Por cada mtodo find del interface home del bean, tiene su correspondiente mtodo ejbFind< type > con la misma firma (parmetros y valor de retorno). ejbLoad y ejbStore : El contenedor llama a estos mtodos para sincronizar el estado del bean con la base de datos subyacente. Cuando un cliente selecciona u obtiene los datos de un bean como en el caso de un mtodo get,
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

77

el contenedor llama al mtodo ejbStore para envar el objeto a la base de datos y llama a ejbLoad para leerlo de nuevo. Cuando un cliente llama a un mtodo find, el contenedor llama a ejbLoad para inicializar el bean con los datos desde la base de datos subyacente. ejbActivate y ejbPassivate: El contenedor llama a estos mtodos para activar o desactivar el estado del bean. La activacin o desactivacin se refieren al intercambio del bean dentro y fuera del almacenamiento temporal para liberar memoria, que podra ocurrir si un bean dado no ha sido llamado por un cliente desde hace mucho tiempo. Las implementaciones de ejbPassivate podran incluir cosas como el cierre de conexiones o ficheros usados por el bean, y para ejbActivate podra incluir cosas como la reapertura de las mismas conexiones o ficheros.

Modificar el cdigo de BonusBean


Esta seccin nos lleva a travs del cdigo de BonusBean con persistencia controlada por el bean. Lo primero que observaremos es que hay mucho ms cdigo que en la versin con persistencia controlada por el contenedor.

Sentencias Import
Las interfaces InitialContext, DataSource, y Connection se importan para establecer conexiones con la base de datos. La interface PreparedStatement se importa para usarlo como plantilla para crear una peticin SQL. La interface ResultSet se importa para manejar accesos a filas de datos devueltas por una consulta. Las clases FinderException y SQLException se importan para manejar excepciones de bsqueda y accesos a bases de datos. package Beans; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.naming.InitialContext; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import javax.ejb.FinderException; import java.sql.SQLException;

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

78

Variables de Ejemplar
Las variables de ejemplar aadidas en esta leccin nos permiten establecer y cerrar conexiones con bases de datos. El string java:comp/env/jdbc/BonusDB indica el nombre de referencia para el recurso, que tambin deberamos especificar cuando aadamos el bean de entidad a la aplicacin J2EE usando la herramienta Deploy. En este ejemplo, la referencia de recursos es un alias a la base de datos Cloudscape ( CloudscapeDB) donde est almacenada la tabla de datos. Despus crearemos la tabla BONUS en CloudscapeDB, y durante el despliegue mapearemos jdbc/BonusDB a jdbc/CloudscapeDB . public class BonusBean implements EntityBean { private EntityContext context; private Connection con; private String dbName = "java:comp/env/jdbc/BonusDB"; private InitialContext ic = null; private PreparedStatement ps = null; private double bonus; private String socsec;

Mtodos de Negocio
Los mtodos de negocio no han cambiado para esta leccin excepto en las llamadas a System.out.println, que nos permiten ver el orden en que se llaman los mtodos de negocio y ciclo de vida durante la ejecucin. public double getBonus() { System.out.println("getBonus"); return this.bonus; } public String getSocSec() { System.out.println("getSocSec"); return this.socsec; }

Mtodos de Ciclo de Vida


Estos mtodos incluyen llamadas a System.out.println para que podamos ver en que orden se llaman durante la ejecucin. ejbCreate La firma del mtodo ejbCreate para esta leccin lanza RemoteException y SQLException adems de CreateException. SQLException es necesaria porque el mtodo ejbCreate proporciona su propio cdigo SQL, y RemoteException es necesaria porque ese mtodo realiza acceso remoto

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

79

Una cosa a observar de esta clase es que devuelve un valor String que es la clave primaria, pero la declaracin para este mtodo en el interface home espera recibir un ejemplar de la clase Bonus. El contenedor usa la clave primaria devuelta por este mtodo para crear un ejemplar de Bonus. public String ejbCreate(double bonus, String socsec) throws RemoteException, CreateException, SQLException { this.socsec=socsec; this.bonus=bonus; System.out.println("Create Method"); try { //Establish database connection ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dbName); con = ds.getConnection(); //Use PreparedStatement to form SQL INSERT statement //to insert into BONUS table ps = con.prepareStatement( "INSERT INTO BONUS VALUES (? , ?)"); //Set 1st PreparedStatement value marked by ? , with //socsec and the 2nd value marked by ?) with bonus ps.setString(1, socsec); ps.setDouble(2, bonus); ps.executeUpdate(); } catch (javax.naming.NamingException ex) { ex.printStackTrace(); } finally { //Close database connection ps.close(); con.close(); } //Return primary key return socsec; } ejbPostCreate Este mtodo tiene la misma firma que ejbCreate, pero no tiene implementacin porque nuestro ejemplo no realiza procesamientos o inicializaciones posteriores a la creaccin. public void ejbPostCreate(double bonus, String socsec) throws RemoteException, CreateException, SQLException { System.out.println("Post Create"); } ejbFindByPrimaryKey La versin controlada por el contenedor de BonusBean no incluia una implementacin de ejbFindByPrimaryKey porque el contenedor podra localizar los registros de la base de datos por su clave primaria si especificamos persistencia
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

80

controlada por el contenedor y proporcionamos un campo de clave primaria durante el despliegue. En esta leccin, BonusBean se despliega con persistencia controlada por el bean por eso debemos proporcionar una implementacin para este mtodo y lanzar una SQLException. La versin controlada por contenedor slo lanzaba RemoteException y FinderException. Si la operacin find localiza un registro con la clave primaria pasada a ejbFindByPrimaryKey, se devuelve el valor de la clave primaria para que el contenedor pueda llamar al mtodo ejbLoad para inicializar BonusBean con los datos bonus y socsec recuperados. Una cosa a observar sobre esta clase es que devuelve un valor String que es la clave primaria, pero la declaracin para este mtodo en el interface home espera recibir un ejemplar de la clase Bonus. El contenedor usa la clave primaria devuelta por este mtodo para crear un ejemplar de Bonus. public String ejbFindByPrimaryKey(String primaryKey) throws RemoteException,FinderException, SQLException { System.out.println("Find by primary key"); try { //Establish database connection ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dbName); con = ds.getConnection(); //Use PreparedStatement to form SQL SELECT statement //to select from BONUS table ps = con.prepareStatement( "SELECT socsec FROM BONUS WHERE socsec = ? "); ps.setString(1, primaryKey); //Use ResultSet to capture SELECT statement results ResultSet rs = ps.executeQuery(); //If ResultSet has a value, the find was successful, //and so initialize and return key if(rs.next()) { key = primaryKey; } else { System.out.println("Find Error"); } } catch (javax.naming.NamingException ex) { ex.printStackTrace(); } finally { //Close database connection ps.close(); con.close(); } //Return primary key return key; } ejbLoad Este mtodo se llama despus de una llamada exitosa a ejbFindByPrimaryKey para cargar y recuperar datos y sincronizar los datos del bean con los de la base de datos. public void ejbLoad() { System.out.println("Load method"); try {
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

81

//Establish database connection ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dbName); con = ds.getConnection(); //Use PreparedStatement to form SQL SELECT statement //to select from BONUS table ps = con.prepareStatement( "SELECT * FROM BONUS WHERE SOCSEC = ?"); ps.setString(1, this.socsec); //Use ResultSet to capture SELECT statement results ResultSet rs = ps.executeQuery(); //If ResultSet has a value, the find was successful if(rs.next()){ this.bonus = rs.getDouble(2); } else { System.out.println("Load Error"); } } catch (java.sql.SQLException ex) { ex.printStackTrace(); } catch (javax.naming.NamingException ex) { ex.printStackTrace(); } finally { try { //Close database connection ps.close(); con.close(); } catch (java.sql.SQLException ex) { ex.printStackTrace(); } } } ejbStore Se llama a este mtodo cuando un cliente selecciona u obtiene datos en el bean para envar el objeto a la base de datos y mantener el bean y la base de datos sincronizados. public void ejbStore() { System.out.println("Store method"); try { //Establish database connection DataSource ds = (DataSource)ic.lookup(dbName); con = ds.getConnection(); //Use PreparedStatement to form SQL UPDATE statement //to update BONUS table ps = con.prepareStatement( "UPDATE BONUS SET BONUS = ? WHERE SOCSEC = ?"); //Set 1st PreparedStatement value marked by ? with //bonus and the 2nd value marked by ?) with socsec ps.setDouble(1, bonus); ps.setString(2, socsec); int rowCount = ps.executeUpdate(); } catch (javax.naming.NamingException ex) { ex.printStackTrace();
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

82

} catch (java.sql.SQLException ex) { ex.printStackTrace(); } finally { try { //Close database connection ps.close(); con.close(); } catch (java.sql.SQLException ex) { ex.printStackTrace(); } } } ejbRemove Se llama a este mtodo cuando un cliente llama al mtodo remove del interface home del bean. El cliente JavaBean de este ejemplo no proporciona un mtodo remove que el cliente pueda llamar para eliminar BonusBean desde su contenedor. De todas formas, aqu podemos ver la implementacin de un mtodo ejbRemove. cuando el contenedor llama a ejbRemove, ste obtiene la clave primaria (socsec) de la variable de ejemplar socsec, elimina el bean de su contenedor, y borra la correspondiente fila de la base de datos. public void ejbRemove() throws RemoteException { System.out.println("Remove method"); try { DataSource ds = (DataSource)ic.lookup(dbName); con = ds.getConnection(); ps = con.prepareStatement( "DELETE FROM BONUS WHERE SOCSEC = ?"); ps.setString(1, socsec); ps.executeUpdate(); } catch (java.sql.SQLException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); try { ps.close(); con.close(); } catch (java.sql.SQLException ex) { ex.printStackTrace(); } } ejbActivate Cuando un bean no se ha utilizado durante mucho tiempo, el contenedor lo desactiva o lo mueve a un almacenamiento temporal donde el contenedor puede rpidamente reactivar el bean en el caso de que algn cliente llame a un mtodo de negocio del bean. Este mtodo llama al mtodo getPrimaryKey en el contexto de entidad para que la clave primaria est disponible para los clientes del bean. Cuando se hace una peticin, el contenedor usa la clave primaria para cargar los datos del bean. public void ejbActivate() { System.out.println("Activate method"); socsec = (String)context.getPrimaryKey(); } ejbPassivate
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

83

Cuando un bean no se ha utilizado durante mucho tiempo, el contenedor lo desactiva o lo mueve a un almacenamiento temporal donde el contenedor puede rpidamente reactivar el bean en el caso de que algn cliente llame a un mtodo de negocio del bean. Este mtodo selecciona la clave primaria a null para liberar memoria mientras el bean est desactivado. public void ejbPassivate() { System.out.println("Passivate method"); socsec = null; } setEntityContext El contenedor llama a este mtodo para inicializar la variable de ejemplar context del bean. Es necesario porque el mtodo ejbActivate llama al mtodo getPrimarykey sobre la variable de ejemplar context para pasar el bean del estado desactivado al de activado. public void setEntityContext( javax.ejb.EntityContext ctx){ System.out.println("setEntityContext method"); this.context = ctx; } unsetEntityContext El contenedor llama a este mtodo para poner a null la variable de ejemplar context despus de que se haya llamado al mtodo ejbRemove para eliminar el bean. Slo los beans de entidad tienen un mtodo unsetEntityContext. public void unsetEntityContext(){ System.out.println("unsetEntityContext method"); ctx = null; } }

Modificar el Cdigo de CalcBean y JBonusBean


Como BonusBean proporciona su propio cdigo SQL, el mtodo CalcBean.calcbonus, que crea ejemplares de BonusBean, tiene que modificarse para lanzar la excepcin java.sql.SQLException. Aqu tenemos la forma de hacer este cambio: public class CalcBean implements SessionBean { BonusHome homebonus; public Bonus calcBonus(int multiplier, double bonus, String socsec) throws RemoteException, SQLException, CreateException { Bonus theBonus = null; double calc = (multiplier*bonus); try { InitialContext ctx = new InitialContext(); Object objref = ctx.lookup("bonus"); homebonus = (BonusHome) PortableRemoteObject.narrow(
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

84

objref, BonusHome.class); } catch (Exception NamingException) { NamingException.printStackTrace(); } //Store data in entity Bean theBonus=homebonus.create(calc, socsec); return theBonus; }

La clase JBonusBean tiene que modificarse para capturar la SQLException lanzada por CalcBean. DuplicateKeyExcpetion es una subclase de CreateException, por eso ser capturada por la sentencia catch (javax.ejb.CreateExceptione). public double getBonusAmt() { if(strMult != null){ Integer integerMult = new Integer(strMult); int multiplier = integerMult.intValue(); try { double bonus = 100.00; theCalculation = homecalc.create(); Bonus theBonus = theCalculation.calcBonus( multiplier, bonus, socsec); Bonus record = theCalculation.getRecord( socsec); bonusAmt = record.getBonus(); socsec = record.getSocSec(); } catch (java.sql.SQLException e) { this.bonusAmt = 0.0; this.socsec = "000"; this.message = e.getMessage(); } catch (javax.ejb.CreateException e) { this.bonusAmt = 0.0; this.socsec = "000"; this.message = e.getMessage(); } catch (java.rmi.RemoteException e) { this.bonusAmt = 0.0; this.socsec = "000"; this.message = e.getMessage(); } genXML(); return this.bonusAmt; } else { this.bonusAmt = 0; this.message = "None."; return this.bonusAmt; } }

Crear la Tabla de la Base de Datos


Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

85

Como este ejemplo usa persistencia controlada por el bean, tenemos que crear la tabla BONUS en la base de datos CloudscapeDB. Con persistencia controladda por el contenedor, la tabla se creaba automticamente. Para mantener las cosas sencillas, la tabla de la base de datos se crea con dos scripts: createTable.sql y cloudTable.sh (Unix) o cloudTable.bat (Windows/NT). Para este ejemplo, el escript createTable.sql va en nuestro directorio ~/J2EE/Beans, y el script cloudTable.sh (Unix) o cloudTable.bat (Windows/NT) va en nuestro directorio ~/J2EE. Para ejecutar estos scripts, vamos al directorio Beans y tecleamos los siguiente: Unix: ../cloudTable.sh Windows/NT: ..\cloudTable.bat

createTable.sql
Este fichero se proporciona con los ficheros fuentes de esta lecccin. drop table bonus; create table bonus (socsec varchar(9) constraint pk_bonus primary key, bonus decimal(10,2)); exit;

cloudTable.bat
Este fichero se proporciona con los ficheros fuentes de esta lecccin. rem cloudTable.bat rem Creates BONUS table in CloudscapeDB. rem rem Place this script in ~\J2EE rem To run: cd ~\J2EE\cloudTable.sh rem rem Change this next line to point to *your* rem j2sdkee1.2.1 installation rem set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2.1 rem rem Everything below goes on one line java -Dij.connection.CloudscapeDB= jdbc:rmi://localhost:1099/jdbc:cloudscape: CloudscapeDB\;create=true -Dcloudscape.system.home= %J2EE_HOME%\cloudscape -classpath %J2EE_HOME%iib\cloudscape\client.jar; %J2EE_HOME%iib\cloudscape\ tools.jar; %J2EE_HOME%iib\cloudscape\cloudscape.jar; %J2EE_HOME%iib\cloudscape\RmiJdbc.jar; %J2EE_HOME%iib\cloudscapeiicense.jar; %CLASSPATH% -ms16m -mx32m COM.cloudscape.tools.ij createTable.sql
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

86

cloudTable.sh
Este fichero se proporciona con los ficheros fuentes de esta lecccin. #!/bin/sh J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2 java -Dij.connection.CloudscapeDB=jdbc:rmi: //localhost:1099/jdbc:cloudscape:CloudscapeDB\; create=true -Dcloudscape.system.home= $J2EE_HOME/cloudscape -classpath $J2EE_HOME/lib/cloudscape/client.jar: $J2EE_HOME/lib/cloudscape/tools.jar: $J2EE_HOME/lib/cloudscape/cloudscape.jar: $J2EE_HOME/lib/cloudscape/RmiJdbc.jar: $J2EE_HOME/lib/cloudscape/license.jar: ${CLASSPATH} -ms16m -mx32m COM.cloudscape.tools.ij createTable.sql

Eliminar el Fichero JAR


Tenemos que actualizar el fichero JAR con el nuevo cdigo del Bean. Si tenemos los dos beans en un slo fichero JAR, tenemos que borrar 2BeansJar y crear uno nuevo. Los pasos para aadir CalcBean son los mismos que los de la leccin Comunicaciones entre Beans. Los pasos para aadir BonusBean son ligeramente diferentes como se describe aqu. Si tenemos los beans en ficheros JAR separados, tenemos que borrar el fichero JAR con BonusBean y crear uno nuevo como se describe aqu. Estas instrucciones empiezan en el momento de aadir los interfaces y las clases de BonusBean al fichero JAR. EJB JAR : Pulsamos Add (el ms cercano a la ventana Contents). Cambiamos de directorio para que el directorio Beans muestre su contenido. Seleccionamos Bonus.class Pulsamos Add . Seleccionamos BonusBean.class Pulsamos Add . Seleccionamos BonusHome.class Pulsamos Add .

Clases Enterprise Bean JAR : Nos aseguramos de ver Beans/Bonus.class, Beans/BonusHome.class, y Beans/BonusBean.class en el display. Pulsamos OK.

EJB JAR :
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

87

Pulsamos Next .

General : Nos aseguramos de que Beans.BonusBean es el nombre de clase, Beans.BonusHome es el interface Home, y Beans.Bonus es el interface Remoto. Introducimos BonusBean como nombre de display. Pulsamos Entity . Pulsamos Next . Selecciones de Entidad: Seleccionamos Bean-managed persistence . La clase de clave primaria es java.lang.String, Observa que la clave primaria tiene que ser un tipo de clase, los tipos primitivos no son vlidos como claves primarias. Pulsamos Next

. Entradas de Entornio: Pulsamos Next. Este sencillo bean no usa propiedades (entradas de entorno). Referencias a Beans Enterprise: Pulsamos Next .

Referencias a Recursos: Pulsamos Add Tecleamos jdbc/BonusDB en la primera columna, debajo de Coded Name. Nos aseguramos de que Type es javax.sql.DataSource, y Authentication es Container . Pulsamos Next. Seguridad: Pulsamos Next. Este sencillo bean no usa roles de seguridad. Control de Transaccin : Seleccionamos Container-managed transactions (si no lo est ya). En la lista de abajo , marcamos como necesarios create , findByPrimaryKey, getBonus y getSocSec. Esto significa que el contenedor arranca una nueva transacin antes de ejecutar estos mtodos. La transacin se enva justo antes de que los mtodos terminen. Pulsamos Next . Revisin de Selecciones: Pulsamos Finish . Ventana Inspecting: Con 2BeansApp seleccionado pulsamos JNDI names. Asignamos calcs a CalcBean , bonus a BonusBean , y jdbc/Cloudscape a jdbc/BonusDB.

Verificar y Desplegar la Aplicacin


Antes de desplegar la aplicacin, es una buena idea ejecutar el verificador. El verificador mostrar los errores en los componentes de la aplicacin como mtodos inexistentes que el compilador no captura. Verificar: Con 2BeansApp seleccionado, elegimos Verifier desde el men Tools.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

88

En el dilogo que aparece, pulsamos OK. La ventana debera decir que no hay ningn fallo. Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicacin. Nota: En la versin 1.2.1 del software podramos obtener un error tests app.WebURI. Esto significa que la herramienta DeployTool no puso la extensin .war al fichero WAR durante su creaccin. Es un error menor y la aplicacin J2EE se despliega sin problemas. Desplegar: Desde el men Tools, elegimos Deploy Application. Se mostrar una caja de dilogo Deploy BonusApp. Verificar que la seleccin de Target Server es un host local o el nombre de un host donde se est ejecutando el servidor J2EE. Marcar la caja Return Client Jar. Al marcar esta caja se crea un ficher JAR con la informacin de despliegue necesaria por el bean de entidad. Pulsamos Next . Nos aseguramos de que los nombres JNDI muestran calcs para CalcBean, bonus para BonusBean y jdbc/Cloudscape para BonusDB. 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 JSPRoot. 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 dilogo que mostrar el estado de la operacin de despliegue. Cuando se haya completado,pulsamos OK.

Ejecutar la Aplicacin
El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la pgina bonus.html apuntamos nuestro navegador a http://localhost:8000/JSPRoot/bonus.html, que es dnde la herramienta de despliegue puso el fichero HTML. Rellenamos un nmero de la seguridad social y un multiplicador. Pulsamos el botn Submit. Bonus.jsp procesa nuestros datos y devuelve una pgina HTML con el bono calculado.

La salida del servidor J2EE podra mostrar los siguientes mensajes cada vez que se intente un acceso a la base de datos.
Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

89

Estos mensajes significan que no se suministraron nombres de usuarios ni passwords para acceder a la base de datos. Podemos ignorar estos mensajes porque los nombres de usuario y las passwords no son necesarios para acceder a la base de datos Cloudscape, y este ejemplo funciona bien sin importarle estos mensajes

Cannot find principal mapping information for data source with JNDI name jdbc/Cloudscape Aqu tenemos una versin ms limpia de la salida del servidor J2EE (el mensaje de arriba fue editado) setEntityContext method Create Method Post Create setEntityContext method Find by primary key Load method getBonus Store method Load method getSocSec Store method Find by primary key Load method getSocSec Store method Load method getBonus Store method <?xml version="1.0"?> <report> <bonusCalc ssnum="777777777" bonusAmt="300.0" /> </report>

Hurfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

90