You are on page 1of 90

JAVA ENTER PRISE EDITION J2EE

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

1

Temario
1. Descripción de la Arquitectura J2EE 1.1 Describir los principales elementos de la arquitectura J2EE. 1.2 Arquitectura para aplicaciones J2EE (definición del contexto) 1.3 Modelo MVA 2. Descripción del Componente EJB 2.1 SessionBean Aplicación Cliente Multi-Capa Software J2EE y Configuración Componentes de Aplicación J2EE Crear la Página HTML Crear y Compilar el Bean de Sesión y el Servlet Ciclo de vida de SessionBean Arrancar el Servidor de Aplicaciones J2EE Aplicación J2EE Crear la aplicación J2EE Crear Componentes Web Especificar el Nombre JNDI y el Contexto Raíz Verificar, Desplegar y Ejecutar la Aplicación Actualizar el Código 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 Aplicación 3. Comunicaciones entre Beans Enterprise 3.1 Cambiar el Bean de Sesión y el Servlet 3.2 Compilar el Bean de Sesión y el Servlet 3.2.1 Arrancar la Plataforma y las Herramientas 3.2.2 Ensamblar la Aplicación J2EE 3.2.3 Verificar, Desplegar y Ejecutar la Aplicación J2EE 4. Construcción de una sencilla aplicación de J2EE 4.1 Como configurar el software para la ejecución de una aplicación J2EE 4.2 Construcción de un SessionBean 4.3 Construcción de un EntityBean 4.4 Construcción del Cliente

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

2

4.4.1 Servlets 4.4.2 JSPs Tecnología JavaServer Pages™ (JSP) Crear la Página JSP Modificar bonus.html Eliminar el Fichero WAR Verificar, Desplegar y Ejecutar la Aplicación J2EE Tecnología 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 códigos Crear la tabla de la base de datos Eliminar el Fichero JAR Verificar, Desplegar y Ejecutar la aplicación

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 técnicos y de planificación estratégica, expertos en arquitectura de sistemas y asesores tecnológicos de departamentos de informática y empresas independientes proveedoras de software. Duración:40 horas cronológicas

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

3

Santiago Chile 4 . Fonos: * 6322497.www.cl .Un Sencillo Bean de Sesión • Ejemplo de Aplicación Cliente Multi-Capa • Software J2EE y Configuración • Configuración del Path y ClassPath • Componentes de Aplicación J2EE • Crear la Página HTML • Código HTML • Crear el Servlet • Sentencias Import • Método init() • Método doGet • Código del Servlet • Crear el Bean de Session • CalcHome • Calc • CalcBean • Compilar el Bean de Sesión y el Servlet • Compilar el Bean de Session • Compilar el Servlet • Arrancar el Servidor de Aplicaciones J2EE • Arrancar la Herramienta DeployTool • DeployTool • Ensamblar la Aplicación J2EE • Crear la aplicación J2EE • Crear el Bean de Sesión • Crear Componentes Web • Especificar el Nombre JNDI y el Contexto Raíz • Verificar y Desplegar la Aplicación J2EE • Ejecutar la Aplicación J2EE • Actualizar el Código 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 Aplicación • Crear el Bean de Entidad • Verificar y Desplegar la aplicación J2EE • Ejecutar la Aplicación 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 Huérfanos 835 piso 20 oficina 2003.*6322102.ciisa. Fax: 6322529 .

html • Arrancar la Plataforma y las Herramientas • Eliminar el Fichero WAR • Verificar y Desplegar la Aplicación J2EE • Ejecutar la Aplicación J2EE Tecnología JavaBeans • Sobre el Ejemplo • Crear bonus.*6322102. Fonos: * 6322497.Comunicaciones entre Beans • Cambiar el Bean de Sesión • CalcHome • Calc • CalcBean • Cambiar el Servlet • Compilar • Compilar el Bean de Sesión • Compilar el Servlet • Arrancar la Plataforma y las Herramientas • Ensamblar la Aplicación • Crear una Nueva aplicación J2EE • Crear un nuevo componente Web.cl .Santiago Chile .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 • Métodos Set • Métodos Get • Arrancar la Plataforma y las Herramientas • Eliminar el Fichero WAR • Crear el Nuevo Fichero WAR • Verificar y Desplegar la Aplicación 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 Huérfanos 835 piso 20 oficina 2003. Fax: 6322529 . • Empaquetar los Beans de Sesión y de Entidad en un Fichero JAR • Verificar y Desplegar la Aplicación J2EE • Ejecutar la Aplicación J2EE Tecnología JavaServer Pages™ (JSP) • Crear la Página JSP • Comentarios • Directivas • Declaraciones • Scriptlets • Variables Predefinidas • Expresiones • Etiquetas Especificas de JSP • Modificar bonus.www.ciisa.

Fax: 6322529 .Santiago Chile 6 .*6322102.• Ejecutar la Aplicación 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 . Fonos: * 6322497.sql • cloudTable.sh Eliminar el Fichero JAR Verificar y Desplegar la Aplicación Ejecutar la Aplicación • • • • • Huérfanos 835 piso 20 oficina 2003.ciisa.bat • cloudTable.cl .eXtensible Markup Language • Marcar y Manejar Texto • Modificar la Clase JavaBean • Prólogo XML • Documento Raíz • Nodos Hijos • Otras Etiquetas XML • Código del JavaBean • Los APIs • SAX y DOM • J2EE • Actualizar y Ejecutar la Aplicación JDBC • • Ciclo de Vida del Bean Modificar el código de BonusBean • Sentencias Import • Variables de Ejemplar • Métodos de Negocio • Métodos de Ciclo de Vida Modificar el Código de CalcBean y JBonusBean Crear la Tabla de la Base de Datos • createTable.www.

Viene con el servidor de aplicaciones J2EE. El SDK J2EE es una definición y especificación operacional no comercial de la plataforma J2EE que Sun Microsystem a liberado para demostraciones. EJB. prototipos y usos educacionales. El servlet usa el API JNDI (Java Naming and Directory Interface™) para buscar un Bean de sesión que realice los cálculos por él.*6322102. Nos iremos encontrando con estas características y herramientas según vayamos avanzando en este tutorial.Introducción Este manual presenta los APIs. Este ejemplo es una aplicación pequeña porque el servlet no ejecuta ninguna lógica de negocio.ciisa.www. La arquitectura de tres capas extiende al cliente estándar de dos capas y el modelo del servidor situando un servidor de aplicaciones multi-capa entre la aplicación cliente no-basada-en-web y la base de datos final. Fax: 6322529 . los cuales se intenta que sean portátiles entre servidores y sistemas operativos. el ejemplo multi-capa tiene cuatro capas.Capitulo I . Un Sencillo Bean de Sesión Esta lección nos presenta la programación de aplicaciones J2EE. es la adaptación de un modelo de componente Java para servidores de bases de datos. la idea tras el EJB es similar a aquella que Microsoft promovió con el Microsoft Transaction Server y tecnologías relacionadas para aislar a los desarrolladores de negocios de la complejidad de crear aplicaciones demasiado complicadas. las herramientas y los servicios que proporciona la Implementación de Referencia de Java 2 Enterprise Edition (J2EE). un servlet y un Bean de sesión. los APIs J2EE. A excepción del aspecto de la portabilidad. base de datos. Las aplicaciones multi-capa pueden consistir en 3 ó 4 capas. Como se ve en. Cada uno de estos funciona como un contenedor para componentes EJB. Fonos: * 6322497. porque no maneja el proceso. El sencillo cálculo lo realiza un Bean de sesión que se ejecuta en el servidor de aplicaciones J2EE. y el servidor secundario descifrará que servicio puede proporcionar y cual deberá ser enviado a otro servidor. y un completo conjunto de herramientas de desarrollo. "La idea es que escribir aplicaciones interrelacionadas es difícil. Los desarrolladores escribirán componentes que requieran de servicios del contenedor EJB. Ejemplo de Aplicación Cliente Multi-Capa Está pequeña aplicación cliente de ejemplo acepta entrada de usuario a través de un formulario HTML que invoca un servlet. lo hace el Bean de sesión. y EJB lo facilita".cl . La arquitectura de cuatro Huérfanos 835 piso 20 oficina 2003. Transacciones y aplicaciones. servidor Web. Por eso el cliente es pequeño.Santiago Chile 7 . y el SDK J2EE mostrándonos como escribir una sencilla y pequeña aplicación Enterprise multi-capa que consiste en una página HTML.

2 Windows: \home\monicap\J2EE\j2sdkee1.capas extiende el modelo de tres capas reemplazando la aplicación cliente con un navegador Web y una página HTML potenciada con las tecnologías servlet/JavaServer Pages™.2. la siguiente lección extiende este mismo ejemplo para acceder al servidor de base de datos en la cuarta capa.2.2. tendrás que cambiarlo por tu nombre de usuario. Fonos: * 6322497.Santiago Chile 8 .1 /home/monicap/J2EE/jdk1.www.cl .2 Huérfanos 835 piso 20 oficina 2003. Mientras que esta lección usa sólo tres o cuatro capas. Nota: Siempre que se utilice monicap en un nombre de path. Fax: 6322529 .1 \home\monicap\J2EE\jdk1. Unix: /home/monicap/J2EE/j2sdkee1. Software J2EE y Configuración Las instrucciones asumen que J2EE y J2SE están instalados en el directorio J2EE debajo del directorio home del usuario.*6322102.ciisa. Lecciones posteriores adaptan el ejemplo para usar las tecnologías JavaServer™ Pages y Extensible Markup Language (XML).2.

Fax: 6322529 . La especificación J2EE define los siguientes componentes de aplicación: • • • • Componentes de Aplicación Cliente Componentes JavaBeans Enterprise Componentes Servlets y JavaServer Pages (también llamados componentes Web) Applets En esta lección. estas funciones podrían ser realizadas por diferentes personas de diferentes compañías. realmente estaremos realizando varias funciones diferentes. la base de datos Cloudscape. verificar y desplegar el entorno de producción.2.*6322102.2.2\bin \home\monicap\J2EE\j2sdkee1.2. Debemos asegurarnos de seleccionar estos path antes de cualquier otro path que pudiéramos tener de viejas instalaciones del JDK.1\bin Configuración del ClassPath La configuración del ClassPath le dice a las herramientas de desarrollo y despliegue de Java 2 dónde encontrar las distintas librerías de clases que usa: Unix: /home/monicap/J2EE/j2sdkee1. Los ficheros WAR y JAR se añaden a la aplicación J2EE y se empaquetan dentro de un fichero Enterprise Archive (EAR) para probar. En realidad. Unix: /home/monicap/J2EE/jdk1.2. un servidor Web que usa capas de socket seguras (SSL) también conocido como HTTP sobre HTTPS.1/bin Windows: \home\monicap\J2EE\jdk1.www. Huérfanos 835 piso 20 oficina 2003. Un componente J2EE es una unidad de software funcional auto-contenida que se ensambla dentro de una aplicación J2EE y que se comunica con otros componentes de aplicación.2. debemos configurar las variables de entorno path y classpath como se describe aquí: Configuración del Path La configuración del Path hace accesibles las herramientas de desarrollo y despliegue desde cualquier lugar de nuestro sistema. Fonos: * 6322497. El servlet está empaquetado con su fichero HTML en un fichero Web Archive (WAR).jar Componentes de Aplicación J2EE Los programadores de aplicaciones J2EE escriben componentes de aplicación J2EE. y los APIs Java para Enterprise. Escribir el código del servlet y del Bean de sesión es una función de desarrollo.Configuración del Path y ClassPath La descarga contiene el servidor de aplicaciones J2EE. Mientras estemos haciendo todos estos pasos para esta lección.1/lib/j2ee. crearemos una aplicación y dos componentes J2EE: un servlet y un Bean de sesión.jar Windows: \home\monicap\J2EE\j2sdkee1.2.2/bin /home/monicap/J2EE/j2sdkee1. mientras que crear la aplicación J2EE y añadir los componentes J2EE a una aplicación es una función de ensamblaje. y las clases e interfaces del Bean de sesión están empaquetadas en un fichero JAR.Santiago Chile 9 .ciisa. herramientas de desarrollo y despliegue.cl .1\lib\j2ee. Para usar estar características.

/cursos/j2ee/L1/clientcode/BonusServlet. El fichero bonus. busca el Bean de sesión. Fax: 6322529 . se llama a BonusServlet porque se ha mapeado a BonusAlias durante el ensamblaje de la aplicación descrito en Ensamblar la Aplicación J2EE.*6322102.html.cl .javaBonusServlet.Santiago Chile 10 . que muestra cómo vería la página HTML el usuario. El servlet devuelve otra página HTML con el valor del "bonus" para que lo vea el usuario.html tiene dos campos de datos en los que usuario puede introducir un número de seguridad social y un multiplicador. La siguiente Figura muestra el flujo de los datos entre el navegador y el Bean de sesión. Código HTML Lo más interesante sobre el código del formulario HTML es el alias usado para invocar a BonusServlet . El ejemplo asume que bonus. Fonos: * 6322497. el Bean de sesión calcula un valor "bonus" y lo devuelve al servlet.Crear la Página HTML La página HTML para esta lección se llama bonus.java recupera el dato del usuario.html está en el directorio /home/monicap/J2EE/ClientCode en UNIX. y le pasa el dato del usuario al Bean de sesión. Cuando el usuario pulsa el botón Submit. Su código HTML está debajo de la .www. 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> Huérfanos 835 piso 20 oficina 2003.ciisa. Cuando el usuario pulsa el botón Submit sobre el formulario HTML. El Bean de sesión se ejecuta en el servidor de aplicaciones J2EE.

La siguiente sección describe las diferentes partes del código del servlet Sentencias Import El código del servlet empieza con sentencias import para los siguientes paquetes: • • • • • javax. javax. La clase HTTPServlet usa la clase ServletException de este paquete para indicar un problema en el servlet. Fax: 6322529 .cl .io para entrada y salida del sistema. que contiene clases servelts HTTP. que contiene clases servlets genéricas (independientes del protocolo).ciisa. el código del servlet hace lo siguiente: • • • • Recupera los datos del usuario Busca el bean de sesión Le pasa los datos al bean de sesión Después de recibir un valor de vuelta desde el bean de sesión.www. javax. crea una página HTML para mostrar el valor devuelto al usuario. java.*6322102. Huérfanos 835 piso 20 oficina 2003. javax.naming para poder usar los APIs Java Naming and Directory Interface (JNDI™) para buscar el interface home del bean de sesión.java está en el directorio /home/monicap/J2EE/ClientCode en UNIX.servlet.servlet.rmi para buscar el interface home del bean de sesión y poner su objeto servidor remoto listo para las omunicaciones.http. La clase HttpServlet usa la clase IOException de este paquete para señalar que se ha producido una excepción de algún tipo de entrada o salida. Durante la ejecución. Fonos: * 6322497.<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.Santiago Chile 11 . La clase HttpServlet está en este paquete.

setContentType("text/html"). String title = "EJB Example".*6322102. y una ServletException si la petición no se puede manejar.intValue().init busca el interface home del bean de sesión y crea su ejemplar.ciisa. El método doGet lanza una IOException si hay algún problema con los datos de entrada o salida cuando maneja la petición. }catch(Exception CreateException){ Huérfanos 835 piso 20 oficina 2003.Santiago Chile 12 . en qué formulario están los datos de la petición.narrow(obj ref. out. bonus). try{ //Retrieve Bonus and Social Security Information String strMult = request.getParameter("SOCSEC"). IOException { String socsec = null.println(title).Método init() El método BonusServlet. homecalc = (CalcHome)PortableRemoteObject.cl .00.lookup("calcs").println("<HTML><HEAD><TITLE>") out.class). El método usa el nombre JNDI especificado durante el ensamblado de componentes ( calcs) para obtener una referencia al interface home por su nombre. out = response. int multiplier = 0. response.0. double calc = 0.www. InitialContext ctx = new InitialContext(). Object objref = ctx. El navegador envía una petición (request) al servlet y el servlet envía una respuesta (response) de vuelta al navegador. //Calculate bonus double bonus = 100. el método doGet crea el interface home y llama al método calcBonus. y usa el objeto response para crear una página HTML en respuesta a la petición del navegador. HttpServletResponse response) throws ServletException. y que cabeceras HTTP se enviarón. PrintWriter out.getParameter( "MULTIPLIER").calcBonus( multiplier. theCalculation = homecalc.getWriter(). La siguiente línea pasa la referencia y la clase del interface home al método PortableRemoteObject. socsec = request. calc = theCalculation.narrow para asegurarse de que la referencia puede forzarse al tipo CalcHome. Fax: 6322529 .create(). Integer integerMult = new Integer(strMult).println("</TITLE></HEAD><BODY>"). Método doGet La lista de parámetros de doGet toma un objeto request y un response. Fonos: * 6322497. out. multiplier = integerMult. La implementación del método accede a información del objeto request para encontrar quién ha hecho la petición. Para calcular el valor del bonus. public void doGet (HttpServletRequest request. CalcHome.

out.getWriter().lookup("calcs").*. out. response.class).println("<HTML><HEAD><TITLE>").println("<P>Bonus Amount: " + calc + "<P>"). import java. } } public void doGet (HttpServletRequest request.servlet. } catch (Exception NamingException) { NamingException. double calc = 0.println("</BODY></HTML>"). out.narrow( objref. out. out. out.printStackTrace().*6322102. import javax.*. Object objref = ctx. import javax.println("<P>Multiplier: " + multiplier + "<P>"). } Código del Servlet Aquí está el código completo: import javax. CalcHome.println("<H1>Bonus Calculation</H1>").www. import Beans.cl . IOException { String socsec = null. out.PortableRemoteObject.http.Santiago Chile 13 . homecalc = (CalcHome)PortableRemoteObject.setContentType("text/html"). PrintWriter out.0. Fonos: * 6322497. public class BonusServlet extends HttpServlet { CalcHome homecalc. } //Display Data out.ciisa.*.printStackTrace(). import javax.io.println("<P>Soc Sec: " + socsec + "<P>").servlet.close().rmi.println(title).println("</TITLE></HEAD><BODY>").*.*. out. int multiplier = 0. HttpServletResponse response) throws ServletException. public void init(ServletConfig config) throws ServletException{ //Look up home interface try{ InitialContext ctx = new InitialContext(). Fax: 6322529 . String title = "EJB Example".CreateException.naming. out = response. Huérfanos 835 piso 20 oficina 2003.

println("<H1>Bonus Calculation</H1>").Santiago Chile 14 .ciisa. mostrado en la caja sombreada.create(). socsec = request. Huérfanos 835 piso 20 oficina 2003. out. } //Display Data out.close(). } catch(Exception CreateException){ CreateException. Fonos: * 6322497.printStackTrace().println("<P>Multiplier: " + multiplier + "<P>"). Si el servidor o el cliente. theCalculation = homecalc. } } Crear el Bean de Session Un bean de sesión representa una conversación temporal con un cliente.www. los servicios relacionados aseguran que los datos del bean de entidad se graban.getParameter("SOCSEC"). out.out. //Get Multiplier and Social Security Information String strMult = request. out.00.*6322102. La siguiente Figura muestra como funcionan el servlet y el bean de sesión como una aplicación J2EE completa una vez que se han ensamblado y desplegado.println("<P>Soc Sec: " + socsec + "<P>"). Fax: 6322529 .calcBonus(multiplier. El contenedor se crea durante el despliegue. multiplier = integerMult. bonus). Integer integerMult = new Integer(strMult). El contenedor. el bean de sesión y sus datos se van. En contraste.println("<P>Bonus Amount: " + calc + "<P>"). } public void destroy() { System.getParameter("MULTIPLIER"). out. se cuelgan. los beans de entidad son persistentes y representan datos en una base de datos.println("</BODY></HTML>"). out. calc = theCalculation.intValue(). Si el servidor o el cliente se bloquean. //Calculate bonus double bonus = 100. es el interface entre el bean de sesión y las funcionalidades especificas de la plataforma de bajo-nivel que soporta el bean de sesión.println("Destroy").try{ Calc theCalculation.cl .

public interface CalcHome extends EJBHome { Calc create() throws CreateException. Compilar el Bean de Sesión. y /cursos/j2ee/L1/Beans/CalcHome. pero también es posible comprar beans enterprise a un proveedor y ensamblarlos dentro de una aplicación J2EE. El interface remoto extiende EJBObject declara el método calcBonus para el cálculo del valor del bonos. package Beans.java . import javax.ciisa. Se lanzará una CreateException si no se puede crear el bean de sesión y una RemoteException si ocurre una excepción relacionada con las comunicaciones durante la ejecución del método remoto. sino que crea un ejemplar de su interface home. public interface Calc extends EJBObject { public double calcBonus(int multiplier. El interface home extiende EJBHome y tiene un método create para crear el bean de sesión en su contendor.java CalcHome. import java. y está implementado por la clase CalcBean. Fax: 6322529 .cl .java están 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. import javax. el servidor de aplicaciones J2EE crea el interface remoto y el bean de sesión. /cursos/j2ee/L1/Beans/Calc. } Calc Cuando se crea el interface home.EJBObject.La siguiente sección muestra el código del bean de sesión. 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. package Beans.ejb.CreateException.*6322102. Cuando se compilen estos ficheros. } Huérfanos 835 piso 20 oficina 2003.rmi.rmi.ejb.Santiago Chile 15 . CalcHome BonusServlet no trabaja directamente con el bean de sesión. import javax.RemoteException.RemoteException. El ejemplo asume que los ficheros /cursos/j2ee/L1/Beans/CalcBean. RemoteException.java.javaCalcBean. import java. Nota: Este ejemplo muestra cómo escribir un bean de sesión. double bonus) throws RemoteException.java Calc. Fonos: * 6322497.EJBHome.rmi.RemoteException.www. Este método requiere que se lance una javax.ejb.

No tenemos que proporcionar comportamiento para estos métodos a menos que necesitemos funcionalidades adicionales.1 CPATH=.ejb.jar javac -d . Los métodos vacíos son del inteface SessionBean. Fonos: * 6322497. } //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 Sesión y el Servlet Para ahorrarnos tecleado. -classpath "$CPATH" Beans/CalcBean.java Huérfanos 835 piso 20 oficina 2003.SessionContext.cl . por ejemplo cuando el bean es añadido o eliminado de su contenedor.ciisa.CalcBean La clase del bean de sesión implementa el interface SessionBean y proporciona el comportamiento para el método calcBonus.java Beans/Calc. Los métodos setSessionContext y ejbCreate son llamados en este orden por el contendor después de que BonusServlet llame al método create CalcHome.SessionBean.rmi. Compilar el Bean de Session Unix #!/bin/sh cd /home/monicap/J2EE J2EE_HOME=/home/monicap/J2EE/j2sdkee1.ejb. package Beans. import javax.RemoteException. import java. return calc. Fax: 6322529 . la forma más sencilla para compilar el bean de sesión y el servlet es con un script (en Unix) o un fichero batch (en Windows).2.java Beans/CalcHome.:$J2EE_HOME/lib/j2ee. public class CalcBean implements SessionBean { public double calcBonus(int multiplier. Estos métodos los llama el contenedor del bean.www. double bonus) { double calc = (multiplier*bonus). import javax.*6322102.Santiago Chile 16 .

1 set CPATH=.jar javac -d ..*6322102.www. Huérfanos 835 piso 20 oficina 2003.java Windows cd \home\monicap\J2EE\ClientCode set J2EE_HOME=\home\monicap\J2EE\j2sdkee1. podemos ignorar los otros mensajes que aparecen.1\bin\j2ee -verbose La opción verbose imprime mensajes de información en la línea de comandos cuando el servidor arranca. Fonos: * 6322497. \home\monicap\J2EE javac -d . Si tenemos el path configurado para que lea el directorio bin.%J2EE_HOME%\lib\j2ee. -classpath "$CPATH" BonusServlet. Cuando veamos J2EE server startup complete . -classpath %CPATH% BonusServlet.1 CPATH=.ciisa..1/bin/j2ee -verbose Windows: j2sdkee1.java Compilar el Servlet Unix #!/bin/sh cd /home/monicap/J2EE/ClientCode J2EE_HOME=/home/monicap/J2EE/j2sdkee1.java Beans/Calc.:$J2EE_HOME/lib/j2ee.2.%J2EE_HOME%\lib\j2ee. tecleamos lo siguiente desde el directorio J2EE: Unix: j2sdkee1. podemos arrancar la herramienta de despliegue.jar: /home/monicap/J2EE javac -d .java Beans/CalcHome.2 set CPATH=.Windows cd \home\monicap\J2EE set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2. El comando para arrancar el servidor está en el directorio bin debajo de nuestra instalación J2EE.cl .2.2. Fax: 6322529 . -classpath %CPATH% Beans/CalcBean.java Arrancar el Servidor de Aplicaciones J2EE Necesitamos arrancar el servidor de aplicaciones J2EE para desplegar y ejecutar el ejemplo.jar.Santiago Chile 17 . Por ahora. vamos directamente al directorio J2EE (entonces nuestra versión 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.

Y la ventana "Server Aplications" nos dice qué aplicaciones tenemos instaladas.Arrancar la Herramienta DeployTool Para ensamblar y desplegar la aplicación J2EE. tenemos que arrancar la herramienta deploytool. veremos que todas estas ventanas nos muestran información. como el directorio bin de nuestra instalación j2sdkee1. La ventana "Servers" nos dice si el servidor de aplicaciones se está ejecutando en un host local.2. La ventana "Local Aplications" muestra las aplicaciones J2EE y sus componentes.2.*6322102. debemos asegurarnos de no arrancar la herramienta desde el directorio raíz (es decir c:\ ). si se encuentra una NullPointerException para BasicFileChooserUI cuando se arranca deploytool. Nota: Huérfanos 835 piso 20 oficina 2003. Si la ejecutamos desde cualquier otro lugar. Por ejemplo c:\winnt\fonts.2. La ventana "Inspecting" muestra información sobre la aplicación o componentes seleccionados. Si tenemos el path configurado para que lea el directorio bin. Cuando sigamos los pasos para ensamblar la aplicación de ejemplo J2EE. vamos directamente al directorio J2EE (entonces nuestra versión real corresponde con lo que veremos en el texto) y tecleamos: deploytool Si esto no funciona.Santiago Chile 18 . Fonos: * 6322497. Fax: 6322529 . hacemos lo siguiente desde el directorio J2EE: Unix: j2sdkee1.ciisa. También.www. añadimos una variable de entorno llamada JAVA_FONTS y seleccionamos el path a c: \<font directory> . DeployTool El herramienta DeployTool mostrada en la siguiente figura tiene cuatro ventanas principales. no encontraremos este problema.1\bin\deploytool Notas: Si ocurre un error de acceso a memoria mientras arrancamos deploytool .cl .1/bin/deploytool Windows: j2sdkee1.

www. Pulsamos sobre New Application . Podemos pulsar sobre Uninstall para desinstalarla. veremos la aplicación listada en esta ventana.ear". que se describen abajo con más detalle. Especificar el contexto raíz para la aplicación J2EE (BonusRoot ).ear. Menu File : Seleccionamos New Application . • Pulsamos sobre Add. hacerle cambios.ear para el Application File Name. pulsamos sobre Next . 5. Especificar un nombre JNDI para el bean enterprise ( calcs). Arrancará el New Enterprise Bean Wizard y mostrará un diágolo de introducción que sumariza los pasos que vamos a tomar. Ensamblar la Aplicación J2EE Ensamblar una aplicación J2EE implica crear una nueva aplicación. Aquí tenemos un sumario de los pasos para ensamblar. Después de desplegar la aplicación. BonusApp aparece en el nombre.ear).ciisa. Crear un nuevo componente web (Bonus. y reinstalarla sin tener que parar y rearrancar el servidor de aplicaciones. Caja de diálogo New Application: • • • Tecleamos BonusApp. 2. En este ejemplo. y prorporciona información de tiempo de ejecución sobre la aplicación.Santiago Chile 19 . 3. Caja de Diálogo EJB JAR: Especificamos la siguiente información: • Enterprise Bean will go in : BonusApp Display name: CalcJar Description: Un sencillo Bean de sesión que calcula un bonus y tiene un método. Crear un nuevo bean enterprise (CalcBean. Pulsamos sobre OK. Pulsamos el botón Browse para abrir el selector de ficheros para seleccionar la localización donde queremos grabar el fichero EAR Selector de Ficheros New Application: • • • • • Localizamos el directorio donde queremos situar el fichero EAR de la aplicación.war). Crear una nueva aplicación J2EE (BonusApp. Fonos: * 6322497. Después de leerlos.A la derecha de la ventana Server Applications hay un botón gris Uninstall. No aseguramos de pulsar el segundo que está cerca de la ventana Contents.jar). Huérfanos 835 piso 20 oficina 2003. En el campo File name. Menú File: Seleccionamos New Enterprise Bean. En la ventana de Local Applications ahora aparecerá " Bonusapp. Hay dos botones en esta pantalla. La meta información mostrada en la ventrana contents describe el fichero JAR y la aplicación J2EE. este directorio es /home/monicap/J2EE . Fax: 6322529 . la localización y la información de contenidos para BonusApp . 1. y en la ventana Inspector a la derecha muestyra el nombre.cl . Pulsamos el botón derecho del ratón en el campo Application Display Name. tecleamos BonusApp.*6322102. y añadirle los componentes de aplicación. 4. Crear la aplicación J2EE Los componentes J2EE se ensamblan dentro de ficheros (EAR) "Enterprise Archive". Crear el Bean de Sesión Los beans Enterprise (tanto de entidad como de sesión) se empaquetan en un fichero JAR.

Seleccionamos CalcBean. y Beans/CalcBean. y proporcionamos una descripción para los contenidos del ficheros JAR. • • • • Caja de Diálogo Environment Entries: Este ejemplo no hace uso de las propiedades (entradas de entorno) pero nosotros si podríamos: • Pulsamos sobre Finish . Nota Importante: La caja de diálogo Add Contents to .Santiago Chile 20 . Pulsamos sobre Add . Se arrancará el New Web Component Wizard y mostrará una ventana que sumariza los pasos que vamos a tomar. Beans/Calc. Menú File : Seleccionamos New Web Component . Beans/CalcHome.class . o JavaServer Pages™) se empaquetan dentro de un fichero Web Archive (WAR).CalcBean Home interface: Beans. Display Name: CalcBean Description: Este fichero JAR contiene el bean de sesión CalcBean.ciisa. pulsamos sobre Next . Una vez en el directorio J2EE.class .class. Caja de diálogo General : Seleccionamos la siguiente información: • classname: Beans. Podemos teclear el nombre del path o usar el navegador para obetenerlo.JAR: vamos al directorio J2EE. Las clases Enterprise Bean JAR se deberían mostrar con el prefijo del nombre de directorio Beans.Calc Bean type: Session y Stateless Especificamos el nombre (el nombre que aparece cuando el fichero JAR se añade a BonusApp en la ventana de "Local Applications"). Caja de diálogo WAR File General Properties : Proporcionamos la siguiente información: Huérfanos 835 piso 20 oficina 2003.class . • • Pulsamos OK. • • • • • • Selecionamos Calc. Veremos el fichero JAR CalcJar. Pulsamos Next. hacemos doble click sobre beans para mostrar el contenido del directorio beans.CalcHome Remote interface: Beans. Después de leerlos. Fonos: * 6322497.JAR se debería parecer a la de la figura siguiente. Verificar que el fichero JAR se añadido realmente a la aplicación J2EE: • Vamos a la ventana "Local Applications" • Pulsamos el gráfico gris en frente de BonusApp . Pulsamos sobre Add .www.Caja de Diálogo Add Files to . • Pulsamos el gráfico gris en frente de CalcJar para ver el bean de sesión CalcBean. Pulsamos sobre Next .class deberían aparecer en la ventana Contents.class . Ahora deberíamos estar de nuevo en la caja de diálogo EJB JAR.*6322102. Fax: 6322529 . Crear Componentes Web Los componentes Web (servlets. Pulsamos sobre Add . Seleccionamos CalcHome.cl .

Fax: 6322529 . Nota: Debemos asegurarnos de añadir bonus.ciisa. Seleccioamos bonus. • Pulsamos sobre Add . • Elegimos de nuevo el directorio ClientCode.cl .class sin el directorio precediendo el nombre. • Seleccionamos BonusServlet. Caja de Diágolo Contents to WAR: La pantalla se debería parecer a la de la siguiente figura Huérfanos 835 piso 20 oficina 2003.*6322102.class. Debemos asegurarnos de que WAR contents muestra el nombre de BonusServlet. Pulsamos sobre Add . Caja de Diálogo Add Contents to WAR: • • • Vamos el directorio ClientCode tecleando ClientCode después de J2EE en el campo Root Directory.html antes de añadir BonusServlet.• • WAR file: BonusApp Display name: BonusWar Description: Este fichero war contiene un servlet y una página HTML Pulsamos Add .www.html.class Pulsamos sobre Next . Debemos asegurarnos de que WAR contents muestra el listado como bonus. Fonos: * 6322497.html sin el directorio ClientCode precediendo al nombre.Santiago Chile 21 .

Caja de diágolo WAR File General Properties : • Pulsamos Next . Caja de diálogo Component Aliases: Huérfanos 835 piso 20 oficina 2003. Fonos: * 6322497.ciisa.*6322102. Caja de Diálogo Component General Properties : • Nos aseguramos de que BonusServlet está seleccionado para la clase Servlet.Santiago Chile 22 . Caja de diálogo Component Initialization Parameters : • Pulsamos Next .cl . • Introducimos un nombre ( BonusServlet ) y una descripción.www. Fax: 6322529 . BonusServlet no usa ningún parámetro de inicialización. Caja de diálogo Choose Component Type: • Selecccionamos Servlet (si no está ya seleccionado) • Puslamos Next .• Pulsamos Finish . • Podemos ignornar las selecciones de Startup y load sequence aquí porque este ejemplo sólo usa un servlet.

podemos ver que el fichero WAR contiene un fichero XML con información estructural y de atributos sobre la aplicación web.Santiago Chile 23 . Tecleamos BonusAlias y pulsamos Return . Tecleamos BonusRoot en la columna de la derecha Pulsamos la tecla Return. El formato del fichero WAR es donde van todas las clases servlet en un punto de entrada con Web-INF/classes. Pulsamos Finish . La ventana "Inspecting" muestra pestañas en la parte superior.2 . y especificar un directorio de contexto raíz donde el desplegador pondrá los componentes web. y el fichero class BonusServlet.html. En el panel de contenido. Especificar el Nombre JNDI y el Contexto Raíz Antes de poder desplegar la aplicación BonusApp y sus componentes. CalcBean se ve en la columna central. Esta situación es la convención parra servidores web compatibles con Servlet 2.html. Este nombre JNDI es el mismo nombre JNDI pasado al método BonusServlet. En la columna más a la derecha bajo el nombre JNDI. Para cambiar el nombre o la descripción: • • • Ponemos el cursor en el campo apropiado en la ventana Lo cambiamos según nuestros deseos Pulsamos la tecla Return para que las ediciones tengan efecto. Fax: 6322529 .cl . La ventana "Inspecting" muestra una pantalla con tres columnas y una fila.www. Durante el despliegue se crea el directorio BonusRoot bajo el directorio public_html en nuestra instalación J2sdkee1. y los ficheros bonus. la clase BonusServlet se sitúa en un directorio raíz de contexto bajo public_html. el fichero bonus. tecleamos calc.lookup.ciisa.• • • Pulsamos Add . cuando se despliega el fichero WAR.*6322102. y una de esas pestañas es JNDI Names.2.html y BonusServlet se copian como muestra en la siguiente figura: Huérfanos 835 piso 20 oficina 2003. Contexto Raíz: • • • Pulsamos la pestaña Web Context en la parte superior de la ventana Inspecting. Fonos: * 6322497. Veremos BonusWar en la columna de la izquierda. Nombre JNDI: • • • • Seleccionamos el fichero BonusApp en la ventana "Local Applications". Este es el mismo nombre de alias que pusimos en el campo ACTION del formulario HTML embebido en el fichero bonus. Sin embargo. Pulsamos la tecla Return. Seleccionamos Select JNDI. tenemos que especificar el nombre JNDI que BonusServlet usa para buscar el bean de sesión CalcBean.

www.Santiago Chile 24 . Fax: 6322529 . Nota: En la versión 1. lo tecleamos y pulsamos Return. pulsamos BonusWar y luego BonusServlet Pulsamos la pestaña Aliases de la parte superior de la ventana Inspecting. Si BonusAlias no está ahí.ciisa.*6322102. Debemos verificar que la selección Target Server es o localhost o el nombre del servidor donde se está ejecutando el J2EE. La única vez que necesitamos seleccionar este check box es cuando despleguemos una aplicación solitaria para el programa cliente. Nota: No debemos seleccionar el check box Return Client Jar. Cerramos la ventana del verificador porque ya estamos listos para desplegar la aplicación. Este ejemplo usa un servlet y una página HTML por eso no debemos seleccionarlo. • Pulsamos Next. Nos aseguramos de que el nombre JNDI muestra calcs. El verificador nos mostrará errores en los componentes de la aplicación como un método no existente en el bean que el compilador no captura.cl . Huérfanos 835 piso 20 oficina 2003. es una buena idea ejecutar el verificador.Alias: • • • En la ventana LocalApp. Este es un bug menor y la apliación J2EE se despliega bien sin notarlo. La ventana nos debería decir si no han fallado los tests. Verificar y Desplegar la Aplicación J2EE Antes de desplegar la aplicación.war al fichero WAR durante su creación. En el diálogo que aparece. lo tecleamos nosotros y pulsamos la tecla Return. Seleccionar este check box crea un fichero Jar con la información de despliegue necesaria para una aplicación solitaria. Si no lo hace. Deberíamos ver BonusAlias en el campo. Pulsamos Finish para empezar el despliegue. lo tecleamos nosotros mismos y pulsamos la tecla Return. Fonos: * 6322497. pulsamos OK. Nos aseguramos de que el nombre Context Root muestra BonusRoot. • • Pulsamos Next . Desplegar: • Desde el menú Tools. • Pulsamos Next. Verificar: • • • Con BonusApp seleccionado. Se mostrará una caja de diálogo Deploy BonusApp. elegimos Verifier desde el menú Tools. Si no lo hace. Esto significa que la herramienta de desarrollo no puso una extensión . elegimos Deploy Application . Aparecerá una caja de diálogo que mostrará el estado de la operación de despliegue.WebURI.2 podríamos obtener un error tests app.

0 Actualizar el Código de Componentes El menú Tools tiene dos opciones de interés. y elegimos una de estas opciones del menú.ciisa. Huérfanos 835 piso 20 oficina 2003.properties en el directorio ~/J2EE/j2sdkee1.*6322102. Estas opciones nos permiten cambiar el código y redesplegar nuestra aplicación con facilidad. lo recompilamos. BonusServlet procesa nuestros datos y devuelve una página HTML con el cálculo del bono. Fax: 6322529 . las tres barras de la izquierda estárán completamente sombreadas.html.www. • Update and Redeploy Application actualiza los ficheros de la aplicación con nuestro nuevo código y redespliega la aplicación sin ejecutar el verificador.html apuntamos nuestro navegador a http://localhost:8000/BonusRoot/bonus. Nota: Si necesitamos usar un puerto diferente porque el puerto 8000 está siendo utilizado por otra cosa. Ejecutar la Aplicación J2EE El servidor web se ejecuta por defecto en el puerto 8000. Rellenamos un multiplicador. • • • Rellenamos un número de seguridad social. Pulsamos el botón Submit. Cuando esto suceda. Simplemente hacemos los cambios en el código. como se ve en la siguiente figura. Para abrir la página bonus.2/config y arrancamos de nuevo el servidor J2EE. En este punto podemos verificar la aplicación o desplegarla.cl .Santiago Chile 25 .• Cuando esté completa. Fonos: * 6322497. pulsamos OK. Bonus Calculation Soc Sec: 777777777 Multiplier: 25 Bonus Amount 2500. editamos el fichero web. que es donde DeployTool puso el fichero HMTL. Son Update Application Files y Update and Redeploy Application. • Update Application Files actualiza los ficheros de la aplicación con nuestro nuevo código.

El SDK J2EE viene con una base de datos Cloudscape.RemoteException. Este método de búsqueda toma la clave primaria como un parámetro. BonusServlet llama al bean de entidad para grabar información sobre el número de la seguridad social y el bono y recuperarlo desde una tabla de la base de datos.ejb. package Beans.rmi. que se usa para recuperar la fila con el valor de la clave primaria que corresponde con el número de la seguridad social pasado a este método.www. import java. y si se actualizan los datos de un bean de entidad. La creación de la tabla de la base de datos y la actualización de las filas ocurre sin escribir nada de código SQL o JDBC. Cuando BonusServlet ejemplariza el interface home y llama a su método create. • • Si ocurre un crash mientras se están actualizando los datos de un bean de entidad. y no necesitamos configuración adicional en nuestro entorno para el bean de entidad. el contenedor crea un ejemplar de BonusBean y llama a su método ejbCreate. Huérfanos 835 piso 20 oficina 2003. los datos de la fila apropiada de la tabla también se actualizan. Si una fila para una clave primada dada (número de seguridad social) ya existe. Los métodos BonusHome.cl . Fonos: * 6322497. si ocurre un crash en medio de una transacción a la base de datos.Añadir un Bean de Entidad Este capitulo amplía el ejemplo de la lección anterior para usar un bean de entidad.create y BonusBean. 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. De echo en este jemplo.*6322102.FinderException. BonusHome La principal diferencia entre el bean de sesión CalcHome de la lección anterior y el bean de entidad BonusHome de esta lección es el método findByPrimaryKey.ejb.Capitulo II . la transacción se "deshace" para evitar que un envío parcial corrompa los datos.ejbCreate deben tener la misma firma . se lanza una java. Fax: 6322529 . Cuando se crea un bean de entidad. la clave primara es el número de la seguridad social. Los datos de un bean de entidad son persistentes porque sobreviven a los crashs. import javax. estos datos son restaurados automáticamente al estado de la última transacción enviada a la base de datos.RemoteException que es manejada por el código cliente BonusServlet.ciisa.ejb. no escribimos ningún código SQL o JDBC™ para crear las operaciones de acceso a la base de datos. La lección sobre Tecnología JDBC y Persistencia Manejada por el Bean nos enseñará como escribir código SQL para un bean de entidad.CreateException. Crear el Bean de Entidad Un bean de entidad representa datos persistentes almacenados en una fila de una tabla de una base de datos. import javax.Santiago Chile 26 . La tabla y el código SQL se generan con la herramienta de Despliegue durante en el ensamble y el despliegue.rmi. los datos se escriben en la fila apropiada de la tabla.EJBHome. En este ejemplo. import javax. Este funcionalidad de acceso a la base de datos añade la cuarta capa y la capa final al pequeño cliente empezado en la lección anterior. El método create toma el valor del bono y de la clave primaria como parámetros.

String socsec) throws CreateException. El interface Bonus declara los métodos getBonus y getSocSec para que el servlet pueda recuperar los datos desde el bean de entidad package Beans. RemoteException.public interface BonusHome extends EJBHome { public Bonus create(double bonus.www. Fax: 6322529 .Santiago Chile 27 . } BonusBean Huérfanos 835 piso 20 oficina 2003.EJBObject.rmi. public Bonus findByPrimaryKey(String socsec) throws FinderException.*6322102. RemoteException.ciisa. Fonos: * 6322497. el contenedor crea el interface remoto y el bean de entidad. public interface Bonus extends EJBObject { public double getBonus() throws RemoteException. public String getSocSec() throws RemoteException.RemoteException.cl . import java. import javax. } Bonus Después de crear el interface home.ejb.

El contenedor llama al método ejbRemove si el interface home tiene el correspondiente método remove que es llamado por el cliente. Luego. package Beans. Los otros métodos vacíos son métodos de retrollamada usados por el contenedor para notificar al bean algún evento que va a ocurrir. Estas operaciones de limpieza e inicialización tienen lugar en momentos específicos durante el ciclo de vida del bean. Cualquier cambio hecho en una variable de ejemplar resulta en una actualización de la fila de la tabla de la base de datos subyacente. public String socsec. Podríamos proporcionar comportamiento para algunos de estos métodos si estámos usando persistencia controlada por el bean. El ejemplar de EntityContext pasado al método setEntityContext tiene métodos que permiten al bean devolver una referencia a sí mismo o para obtener su clave primaria. y otros si necesitamos proporcionar limpieza específica del bean u operaciones de limpieza.rmi.ejb. y el contenedor se lo notifica al bean y llama al método aplicable en el momento apropiado.www. Este sencillo ejemplo no hace procesamiento postcreación. Aquí tenemos una breve descripción de los métodos vacíos: • • • Los métodos ejbPassivate y ejbActivate los llama el contenedor antes de que el contenedor mueva el bean de su almacenamiento.bonus.Santiago Chile 28 . llama al método ejbCreate.cl . el contenedor. import import import import java.ciisa.CreateException. podríamos proporcionar implementaciones para algunos de los métodos vacíos mostrados en el código de BonusBean de abajo. javax.BonusBean es un bean de entidad controlado por contenedor. Este proceso es similar al concepto de intercambio de una página de memoria virtual entre la memoria y el disco.EntityBean. } Huérfanos 835 piso 20 oficina 2003. y luego el contenedor escribe los datos en la base de datos. Se llama al método ejbPostCreate después de ejbCreate y realiza cualquier proceso necesario después de que se cree el bean.RemoteException. } public String getSocSec() { return this.setEntityContext. pero si los tuviera. Este método asigna datos a las variables de ejemplar del bean. Cuando BonusServlet llama a BonusHome. public double getBonus() { return this. Esto significa que el contenedor maneja la persistencia de los datos y el control de las transaciones sin tener que escribir código para transferir datos entre el bean de entidad y la base de datos o definir paquetes de transacciones. private EntityContext ctx.ejb.ejb.create. Fax: 6322529 . javax.EntityContext. public class BonusBean implements EntityBean { public double bonus. Este ejemplo no tiene métodos del tipo set< type >. el cliente podría llamarlos para modificar los datos de las variables de ejemplar del bean. el contenedor llama al método BonusBean.socsec. Fonos: * 6322497. Los métodos ejbLoad y ejbStore los llama el contenedor antes de que se sincronize el estado del bean con la base de datos subyacente.*6322102. javax. Los métodos getBonus y getSocSec son llamados por los clientes para recuperar datos almacenados en variables de ejemplar. Si por alguna razón queremos que el bean de entidad maneje su propia persistencia o las transacciones.

String socsec) throws CreateException{ //Called by container after setEntityContext this.cl . 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 } } Huérfanos 835 piso 20 oficina 2003.Santiago Chile 29 .www. return null. Fax: 6322529 . } public void ejbPostCreate(double bonus.public String ejbCreate(double bonus. Fonos: * 6322497. this.ciisa.bonus=bonus.*6322102.socsec=socsec.

lookup("bonus"). BonusHome homebonus.printStackTrace(). Object objref = ctx. theCalculation = homecalc. El método init de esta lección busca el bean de sesión CalcBean.www. calc = theCalculation. multiplier = integerMult. el bono calculado. y los datos recuperados desde la fila de tabla de la base de datos. el bono calculado.intValue(). } catch (Exception NamingException) { NamingException. En el evento de una clave duplicada. La tabla de la base de datos subyacente no puede tener dos filas con la misma clave primaria.create para crear un ejemplar del bean de entidad y la correspondiente fila en la tabla de la base de datos subyacente.findByPrimaryKey para recuperar el mismo registro por su clave primaria (número de la seguridad social).class). Fonos: * 6322497.class). Fax: 6322529 . se llama al método BonusHome. Después de crear la tabla. Bonus theBonus.narrow( objref.ciisa. y el bean de entidad BonusBean. record.create(). por eso si pasamos el mismo número de la seguridad social. el servlet devuelve una página HTML con los datos pasados originalmente. //Retrieve Bonus and Social Security Information String strMult = request. homebonus=( BonusHome)PortableRemoteObject. y un mensaje de error de clave duplicada: try { Calc theCalculation.Cambiar el Servlet El código de esta lección es muy similar al de la página anterior con cambios en los métodos init y doGet.getParameter("SOCSEC"). se devuelve una página HTML al navegador mostrado los datos pasados originalmente. CalcHome. se llama al método BonusHome. //Create row in table Huérfanos 835 piso 20 oficina 2003.lookup("calcs").*6322102. Después de llamar a calcBonus para calcular el bono. //Calculate bonus double bonus = 100. La sentencia catch captura y maneja los valores de claves primaria duplicados (números de seguridad social.//Calculate bonus Integer integerMult = new Integer(strMult). bonus). socsec = request. public class BonusServlet extends HttpServlet { CalcHome homecalc.cl .narrow( objref2. homecalc=(CalcHome) PortableRemoteObject. BonusHome. } } La sentencia try en el método doGet crea los interfaces home de CalcBean y BonusBean.00. Object objref2 = ctx.getParameter( "MULTIPLIER"). Luego.calcBonus( multiplier. public void init(ServletConfig config) throws ServletException{ try { InitialContext ctx = new InitialContext().Santiago Chile 30 . el servlet captura el error antes de intentar crear el bean de entidad.

println("<P>Soc Sec passed in: " + theBonus.*6322102.1 CPATH=. } catch (Exception CreateException) { CreateException. out. out. record = homebonus.getSocSec() + "<P>").2.println("<H1>Bonus Calculation</H1>").println("<P>Bonus Amount retrieved: " + record.jar javac -d . compilamos el Bean de entidad y el servlet. Fax: 6322529 . out.getSocSec() + "<P>").www.ciisa.DuplicateKeyException e) { String message = e. -classpath "$CPATH" Beans/BonusBean.theBonus = homebonus.java Beans/Bonus.println("<P>Bonus Amount calculated: " + calc + "<P>").getBonus() + "<P>").println("<P>Soc Sec passed in: " + socsec + "<P>").println("<P>Soc Sec retrieved: " + record. classpath y dónde situar los ficheros fuentes. //Display data out. out.getMessage().2. out.1 Huérfanos 835 piso 20 oficina 2003. Puedes volver a la lección anterior para ver la configuración del path.println("</BODY></HTML>").Santiago Chile 31 . Compilar el Bean de Entidad Unix #!/bin/sh cd /home/monicap/J2EE J2EE_HOME=/home/monicap/J2EE/j2sdkee1.println("<P>Bonus Amount calculated: " + theBonus.:$J2EE_HOME/lib/j2ee. out.println("<P>Multiplier passed in: " + multiplier + "<P>").findByPrimaryKey(socsec).println("</BODY></HTML>"). out.cl . out.java Beans/BonusHome.getBonus() + "<P>"). out.printStackTrace().println("<P>" + message + "<P>").println("<P>Multiplier passed in: " + multiplier + "<P>"). } } Compilar Primero. out. //Catch duplicate key error } catch (javax.println("<H1>Bonus Calculation</H1>"). //Display data out.create(calc.ejb.java Windows cd \home\monicap\J2EE set J2EE_HOME=\home\monicap\J2EE\j2sdkee1. out. socsec). Fonos: * 6322497.

Fax: 6322529 .1\bin\deploytool j2sdkee1.cl .jar:/home/monicap/J2EE javac -d .2.jar.Santiago Chile 32 .:$J2EE_HOME/lib/j2ee. la herramienta Deploy y la base de datos Cloudscape.1/bin/cloudscape -start Windows j2sdkee1.set CPATH=.ciisa.java Beans/Bonus. -classpath %CPATH% BonusServlet.java Windows: cd \home\monicap\J2EE\ClientCode set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.java Arrancar la Plataforma y las Herramientas Para ejecutar este ejemplo.2.%J2EE_HOME%\lib\j2ee. En diferentes ventanas. -classpath "$CPATH" BonusServlet.1/bin/deploytool j2sdkee1.1 CPATH=. tecleamos los siguientes comandos.www. necesitamos arrancar el servidor J2EE.2.2.2..jar javac -d .2.java Compilar el Servlet Unix: cd /home/monicap/J2EE/ClientCode J2EE_HOME=/home/monicap/J2EE/j2sdkee1. tecleamos esto desde el directorio J2EE: Unix j2sdkee1. -classpath %CPATH% Beans/BonusBean.*6322102.1 set CPATH=.1/bin/j2ee -verbose j2sdkee1.2.java Bean s/BonusHome.1\bin\cloudscape -start Ensamblar y Desplegar Los pasos de esta sección son: • • Actualizar el Fichero de Aplicación Crear el Bean de Entidad Actualizar el Fichero de Aplicación Huérfanos 835 piso 20 oficina 2003..2. j2ee -verbose deploytool cloudscape -start Si esto no funciona. Fonos: * 6322497.1\bin\j2ee -verbose j2sdkee1.%J2EE_HOME%\lib\j2ee. \home\monicap\J2EE javac -d .

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

Nota: Se desinstalará automáticamente la aplicación BonusApp de la lección 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 sesión cubiertos en la lección anterior. Sin embargo, hay algunas diferencias, y se explican aquí: Nota: En esta lección, el bean de entidad va en un ficjero JAR separado del bean de sesión para continuar el ejemplo de la lección anterior con el menor número de cambios. Sin embargo, como estos beans tienen funcionalidades relacionadas podríamos empaquetarlos y desplegarlos en el mismo fichero JAR. Vermos como hacer esto en la siguiente lección. Menu File: • Seleccionamos New Enterprise Bean.

Introducción : • 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 más cercano a la ventana Contents).

Añadir 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.

Huérfanos 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 .

Configuración 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 .

Huérfanos 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 Transacción : • 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 transacción antes de ejecutar estos métodos. Las transacciones se envían justo antes de que los métodos 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

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

35

Antes de poder desplegar la aplicación J2EE, necesitamos especificar las condiciones de despliegue para el bean de entidad y generar el SQL. Aquí está cómo hacerlo: Ventana Local Applications: • Seleccionamos BonusBean . Ventana Inspecting: • Seleccionamos Entity • Pulsamos el botón Deployment Settings de la parte inferior izquierda. Configuración de Despliegue: • Especificamos jdbc/Cloudscape (con una C maýuscula en Cloudscape) para el nombre JNDI de la base de datos. • Pulsamos Return. • Nos aseguramos de que las cajas Create table on deploy y Delete table on Deploy están marcadas. • Ahora pulsamos Generate SQL .

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

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

36

Cuando se complete la generación de SQL, seleccionamos el método findByPrimaryKey en la caja EJB method. Aparecerá una secuencia SQL a la derecha. Debería leerse SELECT "socsec" FROM "BonusBeanTable" WHERE "socsec"=?. El interrogante representa el parámetro pasado por el método findByPrimaryKey. Pulsamos OK.

Verificar y Desplegar la aplicación J2EE
Verificar: • • • Con BonusApp seleccionado, elegimos Verifier desde el menú Tools. En el diálogo que aparece, pulsamos OK. La ventana debería decirnos que no ha fallado ningún test. Cerramos la ventana del verificador porque ya estamos listos para desplegar la aplicación.

Nota: En la versión 1.2 del software podría obtener un error tests app.WebURI. La Aplicación 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 aplicación solitaria para el programa cliente. Este ejemplo usa un servlet y una página HTML por lo que no debe estár marcada. Esta caja crea un fichero JAR con toda la información de despliegue necesaria para una aplicación solitaria. • • • • • Pulsamos Next. Nos aseguramos de que 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 Aplicación J2EE
El servidor web se ejecuta por defecto en el puerto 8000. Para abrir la página bonus.html apuntamos nuestros navegador a http://localhost:8000/BonusRoot/bonus.html, que es donde DeployTool puso el fichero HMTL. Rellenamos un número de la seguridad social y un múltiplicador, y pulsamos el botón Submit. BonusServlet procesa nuestros datos y devuelve una página HTML con el bono calculado. Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 25 Bonus Amount calculated: 2500.0 Soc Sec retrieved: 7777777777 Bonus Amount retrieved: 2500.0
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl - Santiago Chile

37

veremos esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Bonus Amount calculated: 200. Fax: 6322529 .Si volvemos al código de bonus.0 Duplicate primary key.*6322102. Huérfanos 835 piso 20 oficina 2003.html y cambiamos el multiplicador por 2. pero usamos el mismo número de la seguridad social.Santiago Chile 38 . Fonos: * 6322497.www.ciisa.cl .

import javax. y luego buscaba y creaba un bean de entidad para almacenar el valor del bono y el número de la seuridad social asociado.*6322102. package Beans. import java.CreateException. Nota: Algunas personas tienen problemas con esta lección al trabajar 2 beans en un fichero JAR.Santiago Chile 39 .ejb.ejb. Por eso.cl . Cambiar el Bean de Sesión En esta lección y como se ve en la siguiente figura el bean de entidad es un cliente del bean de sesión. Este capitulo modifica el ejemplo para que el bean de sesión busque y cree el bean de entidad.ciisa. están empaquetados en un sólo fichero JAR para su despliegue. Tiene el mismo método create que devuelve un ejemplar del interface remoto.Capitulo III .RemoteException. CalcHome El interface CalcHome no se modifica. Esto significa que el bean de entidad obtiene sus datos del bean del sesión en vez de BonusServlet como lo hizo en la . Fax: 6322529 . public interface CalcHome extends EJBHome { public Calc create() throws CreateException. Podríamos necesitar parar y rearrancar el servidor y las herramientas antes de poder generar el SQL y desplegar.rmi.www. Como el bean de sesión y el de entidad trabajan juntos. podemos borrar el fichero JAR con los dos beans y poner cada bean en su propio fichero JAR. RemoteException.EJBHome. Si sucede esto. el servlet buscaba y creaba un bean de sesión para realizar el cálculo de un bono. import javax. se modifica el método calcBonus del bean de sesión para tomar el número de la seguridad social como un parámetro y crear el bean de entidad. Fonos: * 6322497.Comunicaciones entre Beans En el capitulo anterior. } Huérfanos 835 piso 20 oficina 2003.

pero capturamos CreateException. String socsec) throws RemoteException. CreateException. javax.RemoteException.ejb.InitialContext.SessionBean. public interface Calc extends EJBObject { public Bonus calcBonus(int multiplier. Por eso CalcBean puede pasar el bono y el número de la seguridad social al bean de entidad después de calcular el valor del bono. import javax.ejb. Huérfanos 835 piso 20 oficina 2003. //Throw DuplicateKeyException and CreateException //so BonusServlet can catch and handle these //exception conditions.rmi. DuplicateKeyException.*6322102. La variable homebonus es una variable de ejemplar para que pueda ser usada en el método calcBonus para buscar el bean de entidad y en el método getRecord para localizar el bean de entidad correspondiente al número de la seguridad social. double bonus. package Beans.CreateException. javax. import java. public Bonus getRecord(String socsec) throws RemoteException.DuplicateKeyException. import javax.rmi. import import import import import import import java.ejb. } CalcBean El código para crear el bean de entidad se ha movido desde BonusServlet hasta calcBonus para que el bono y el número de la seguridad social puedan escribirse en el bean de entidad después de haber calculado el bono.Calc El método calcBonus del interface Calc se ha modificado para tomar el número de la seguridad social como parámetro. javax.DuplicateKeyException.cl .Santiago Chile 40 .rmi.EJBObject. DuplicateKeyException desciende de CreateException. Se añade un nuevo método getRecord para que CalcBean peuda encontrar el bean de entidad por sus clave primaria (el número de la seguridad social). Si diseñamos el método calcBonus para lanzar DuplicateKeyException .ciisa. public class CalcBean implements SessionBean { BonusHome homebonus. Fonos: * 6322497. javax.PortableRemoteObject. Fax: 6322529 .ejb.naming. import javax.RemoteException.ejb. Esto es por lo que BonusServlet puede capturar y manejar cualquiera de estas condiciones de excepción.www.CreateException.SessionContext. javax. package Beans. También.ejb. la firma del método calcBonus lanza DuplicateKeyException y CreateException.ejb. El atajo es hacer que calcBonus lance DuplicateKeyException y CreateException . DuplicateKeyException no se lanzará. javax.

FinderException e) { e.narrow( objref. } return theBonus.printStackTrace().cl .printStackTrace().RemoteException e) { String message = e. } catch (java. homebonus = (BonusHome) PortableRemoteObject.create(calc.Santiago Chile 41 .lookup("bonus"). } return record.getMessage(). } public Bonus getRecord(String socsec) { Bonus record = null. Huérfanos 835 piso 20 oficina 2003.RemoteException e) { String message = e. } public void ejbCreate() { } public void setSessionContext( SessionContext context){ } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } public void ejbLoad() { } public void ejbStore() { } } Cambiar el Servlet El programa BonusServlet es muy similar a la versión de la Lección anterior con algunos cambios en los métodos init y doGet. Fonos: * 6322497. double bonus. e.rmi.www. double calc = (multiplier*bonus). } catch (java. //Use primary key to retrieve data from entity bean try { record = homebonus.*6322102.public Bonus calcBonus(int multiplier. } catch (javax. } catch (Exception NamingException) { NamingException. socsec). try { InitialContext ctx = new InitialContext(). CreateException { Bonus theBonus = null.class).rmi.getMessage(). El método init para esta sección sólo busca el bean de sesión. } //Store data in entity bean try { theBonus = homebonus.printStackTrace().ciisa. Fax: 6322529 .findByPrimaryKey(socsec). BonusHome. String socsec) throws DuplicateKeyException.ejb. Object objref = ctx.

} } La sentencia try del método doGet calcula el bono. Object objref = ctx.getBonus() + "<P>"). CalcHome. } catch (javax. //Calculate bonus double bonus = 100.www. socsec = request.*6322102.println("<P>Bonus Amount retrieved: " + record. la sentencia catch captura y maneja valores de claves primarias duplicadas (números de la seguridad social). Si el método se completa con éxito. socsec).DuplicateKeyException e) { String message = e. //Need Bonus variables because CalcBean methods //called in the doGet method return instances //of type Bonus Bonus theBonus. Duplicate primary key.printStackTrace(). out. theCalculation = homecalc. bonus. Si el método calcBonus lanza una DuplicateKeyException. } catch (Exception NamingException) { NamingException. //Call session bean //Pass 3 parameters:multiplier. out.calcBonus( multiplier. try { Calc theCalculation. crea el interface home del bean de sesión y llama a los métodos calcBonus y getRecord. public void init(ServletConfig config) throws ServletException{ try { InitialContext ctx = new InitialContext(). Huérfanos 835 piso 20 oficina 2003.//Calculate bonus Integer integerMult = new Integer(strMult).intValue(). Fax: 6322529 . record = theCalculation. and socsec theBonus = theCalculation. Como en la lección anterior. se devuelve una página HTML que muestra los datos recuperados desde el bean de entidad.ciisa.getMessage().ejb. y un mensaje de excepción.println("<P>Soc Sec retrieved: " + record.getParameter( "MULTIPLIER").getSocSec() + "<P>").narrow( objref.getRecord(socsec). //Display data returned by session bean out.lookup("calcs"). multiplier = integerMult.class). se devuelve una página HTML mostrando el número de la seguridad social y el multiplicador pasados. homecalc = (CalcHome) PortableRemoteObject.cl . Fonos: * 6322497.println("</BODY></HTML>").Santiago Chile 42 . record.getParameter("SOCSEC"). //Retrieve Bonus and Social Security Information String strMult = request.println("<H1>Bonus Calculation</H1>").public class BonusServlet extends HttpServlet { CalcHome homecalc.00. bonus.create(). out.

Fonos: * 6322497. out.java Beans/CalcHome.jar: /home/monicap/J2EE javac -d . Puedes referirte a la primera lección para ver la configuración del path y del classpath y más información sobre dónde situar los ficheros fuente.out.cl .java Beans/Calc.jar:\home\monicap\J2EE javac -d .java Huérfanos 835 piso 20 oficina 2003..java Windows: cd \home\monicap\J2EE\ClientCode set J2EE_HOME=\home\monicap\J2EE\j2sdkee1. } Compilar Primero compilamos el bean de sesión y el servlet.java Compilar el Servlet Unix: cd /home/monicap/J2EE/ClientCode J2EE_HOME=/home/monicap/J2EE/j2sdkee1.java Beans/CalcHome.println("<P>Multiplier passed in: " + multiplier + "<P>").2.www. Compilar el Bean de Sesión Unix #!/bin/sh cd /home/monicap/J2EE J2EE_HOME=/home/monicap/J2EE/j2sdkee1. -classpath "$CPATH" Beans/CalcBean..Santiago Chile 43 .2.println("<P>Soc Sec passed in: " + socsec + "<P>").println("</BODY></HTML>"). out.:$J2EE_HOME/lib/j2ee. out.1 CPATH=.java Windows cd \home\monicap\J2EE set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2 CPATH=. } catch (Exception CreateException) { CreateException.ciisa. Fax: 6322529 .1 set CPATH=.%J2EE_HOME%\lib\j2ee. -classpath "$CPATH" BonusServlet.java Beans/Calc.%J2EE_HOME%\lib\j2ee.println("<H1>Bonus Calculation</H1>").jar javac -d .printStackTrace(). -classpath %CPATH% Beans/CalcBean. -classpath %CPATH% BonusServlet.jar javac -d .*6322102.2 set CPATH=.:$J2EE_HOME/lib/j2ee.

1/bin/deploytool j2sdkee1. Fax: 6322529 .2.1\bin\j2ee -verbose j2sdkee1. Crear una Nueva aplicación J2EE En vez de actualizar la aplicación J2EE de las lecciones anteriores. Fonos: * 6322497.cl . tecleamos esto desde el directorior J2EE: Unix j2sdkee1.1/bin/j2ee -verbose j2sdkee1.2. la herramienta Deploy y la base de datos Cloudscape. seleccionamos New Application .ciisa. Empaquetar los Beans de Sesión y de Entidad en un fichero JAR.2. Huérfanos 835 piso 20 oficina 2003.*6322102.www. necesitamos arrancar el servidor J2EE.Santiago Chile 44 .Arrancar la Plataforma y las Herramientas Para ejecutar este ejemplo. Pulsamos con el botón derecho del ratón en el campo Application Display Name. Crear un nuevo componente Web. Pulsamos el botón Browse para abrir el selector de ficheros y seleccionar la localización donde queremos grabar el fichero EAR de la aplicación.2.1\bin\cloudscape -start Ensamblar la Aplicación Los pasos de esta sección incluyen: • • • Crear una nueva aplicación J2EE. estos pasos crean una nueva aplicación J2EE. j2ee -verbose deploytool cloudscape -start Si esto no funciona. En diferentes ventanas.2. tecleamos los siguientes comandos.2.1\bin\deploytool j2sdkee1. Aparecerá 2BeansApp como nombre.1/bin/cloudscape -start Windows j2sdkee1. Borrar BonusApp: • • Pulsamos BonusApp para que se ilumine Seleccionamos Delete desde el menú Edit Crear 2BeansApp : • • • Desde el menú File.

• Nos aseguramos de seleccionar Describe a servlet. Fax: 6322529 . Con 2BeansApp seleccionado: File Menu: • Seleccionamos New Web Component.www. Choose Component Type: .Selector de ficheros New Application : • • • • • Localizamos el directorio donde queremos situar el fichero de aplicación EAR. Ventana Inspecting: Huérfanos 835 piso 20 oficina 2003. Component General Properties : • Hacemos la clase de servlet BonusServlet. Estos pasos que se presentaron en la primera lección se sumarizan abajo.html • Pulsamos Next • Vamos al directorio ClientCode y añadimos BonusServlet. • Pulsamos Next. • Pulsamos Next. • Pulsamos Add • Vamos al directorio ClientCode y añadimos bonus. tecleamos 2BeansApp.class • Pulsamos Finish.Santiago Chile 45 . En el campo File name.ear. War File General Properties : • Pulsamos Next. Component Aliases : • Especificamos BonusAlias • Pulsamos Finish. • Pulsamos Next. • Hacemos el nombre de display BonusServlet . Pulsamos OK.ciisa.*6322102. Crear un nuevo componente Web.cl . Component Initialization Parameters . Introducción : • Leemos y Pulsamos Next War File General Properties : • Especificamos BonusWar para el nombre. Ahora. el directorio es /export/home/monicap/J2EE. En este ejemplo. Fonos: * 6322497. Pulsamos New Application. veremos los pasos para crear el fichero WAR.

Este sencillo bean de sesión no usa propiedades (entradas de entorno) Referencias a Beans Enterprise: • Pulsamos Next.Calc es el interface remoto.Santiago Chile 46 .www. Menú File: • Seleccionamos New Enterprise Bean.*6322102. Entradas de Entorno: • Pulsamos Next. Para hacer esto. • Pulsamos Add (el más cercano a la ventana Contents). • Cambiamos el directorio para que el directorio Beans muestre su contenido. Empaquetar los Beans de Sesión y de Entidad en un Fichero JAR En esta lección.class • Pulsamos Add. y Beans/CalcBean. • Seleccionamos CalcHome. • Seleccionamos Calc. Fax: 6322529 . Beans. pondremos los beans de sesión y de entidad en el mismo fichero JAR. EJB JAR : • Nos aseguramos de que 2BeansApp se muestra en el campo Enterprise Bean will go in . primero creamos el fichero JAR con sólo el bean de sesión.ciisa. • Especificamos 2BeansJar como nombre. Huérfanos 835 piso 20 oficina 2003. • Introducimos CalcBean como nomre de display. General : • CalcBean es el nombre de la clase. EJB JAR : • Pulsamos Next.class • Pulsamos Add . Introducción : • Leemos y pulsamos Next . • Pulsamos Next. y Beans. y luego le añadimos el bean de entidad. Fonos: * 6322497. Beans/CalcHome.class • Pulsamos Add .class en la pantalla. • Pulsamos session and stateless. Las referencias se manejarán durante el despliegue mejor que aquí.CalcHome es el interface Home.cl . • Clases Enterprise Bean JAR : • Nos aseguramos de que vemos Beans/Calc. Crear JAR con el Bean de Sesión Con 2BeansApp seleccionado.class . • Seleccionamos CalcBean. • Pulsamos OK.class.• • Seleccionamos Web Context Especificamos BonusRoot.

Referencias a Recursos: • Pulsamos Next. • Pulsamos OK. Este sencillo bean de sesión no busca ningún objeto de base de datos o sesión JavaMail™.www. • En la ventana Inspecting seleccionamos JNDI names. Control de Transaciones : • Seleccionamos Container-managed transactions (si no lo está ya).class • Pulsamos Add. Local Applications: • Seleccionamos 2BeansApp . Este sencillo bean de sesión no usa roles de seguridad.Santiago Chile 47 . La transación se envía justo antes de que los métodos terminen. • En la lista de abajo hacemos necesarios calcBonus. Fax: 6322529 . • Seleccionamos Bonus.*6322102. EJB JAR : • Nos aseguramos de que 2BeansJar se muestra en el campo Enterprise Bean will go in . • Seleccionamos BonusHome. General : Huérfanos 835 piso 20 oficina 2003. Fonos: * 6322497. Enterprise Bean JAR classes : • Nos aseguramos de ver Beans/Bonus. File Menu: • Seleccionamos New Enterprise Bean Introduction : • Leemos y pulsamos Next. y Beans/BonusBean. Esta selección añadirá el nuevo bean al fichero JAR existente en lugar de ponerlo en un nuevo fichero JAR.class. • Pulsamos Add (el más cercano a la ventana Contents). Esto significa que el contenedor arranca una nueva transación antes de ejecutar estos métodos. Añadir el Bean de Entidad Con 2BeansApp seleccionado. y getRecord.cl . • Pulsamos Next. • Cambiamos el directorio para que el directorio Beans muestre su contenido.class en el display.class • Pulsamos Add .ciisa.class • Pulsamos Add . le damos el nombre CalcBean JNDI de calcs. • Seleccionamos BonusBean. Seguridad: • Pulsamos Next.class . Beans/BonusHome. y pulsamos la tecla Return. EJB JAR : • Pulsamos Next . Revisar configuraciones: • Pulsamos Finish .

La transación se envía justo antes de que los métodos terminen. Fonos: * 6322497. Control de Transaciones : • Seleccionamos Container-managed transactions (si no lo está ya) • En la lista de abajo hacemos necesarios create . • En la ventana inferior. Introducimos BonusBean como nombre de pantalla. Review Settings: • Pulsamos Finish . y Beans. Huérfanos 835 piso 20 oficina 2003. Enterprise Bean References: • Pulsamos Next. Fax: 6322529 .www. • En la ventana Inspecting. Este sencillo Bean no usa roles de seguridad.Santiago Chile 48 .String.BonusHome es el interface Home. Entity Settings: • Seleccionamos Container managed persistence . Este sencillo bean no usa propiedades (entradas de entorno). findByPrimaryKey. necesitamos especificar las configuraciones de despliegue para el bean de entidad y generar el SQL: Ventana Local Applications: • Seleccionamos BonusBean. marcamos bonus y socsec. Esto significa que el contenedor arrancará una nueva transación antes de ejecutar estos métodos.• • • • Nos aseguramos de que Beans. dando a BonusBean el nombre JNDI de bonus y a CalcBean el nombre JNDI de calcs • Pulsamos la tecla Return después de cada entrada. la clase de clave primaria es java. Los tipos primitivos no son válidos para claves primarias.BonusBean es el nombre de la clase. seleccionamos JNDI names. Resource References: • Pulsamos Next. Este sencillo bean no busca objetos de base de datos ni sesiones JavaMail™. Pulsamos Next .Bonus es el interface remoto. Pulsamos Entity .ciisa. getBonus y getSocSec. • Pulsamos Next . • Pulsamos Next . Environment Entries: • Pulsamos Next . Seguridad: • Pulsamos Next.lang. Observa que la clave primara tiene que ser un tipo de clase. Local Applications: • Seleccionamos 2BeansApp . Este sencillo bean no referencia otros beans enterprise. Ventana Inspecting: • Seleccionamos Entity • Pulsamos el botón Deployment Settings inferior derecha. y el nombre del campo de la clave primaria es socsec.cl . Beans.*6322102. Antes de poder desplegar la aplicación J2EE.

Fax: 6322529 . Pulsamos OK. Huérfanos 835 piso 20 oficina 2003. En el diálogo que aparece. es una buena idea ejecutar el verificador. Fonos: * 6322497.2.1 del software podríamos obtener un error tests app. Desplegar: • Desde el menú Tools. La ventana debería decir que no hay ningún fallo.WebURI. Aparecerá una sentencia SQL a la derecha.Ventana Deployment Settings: • Especificar jdbc/Cloudscape (con una C mayúsculas en Cloudscape) para el nombre JNDI de la base de datos.*6322102. Nota: Si obtenemos un error de que la conexión fue rechazada. El verificador mostrará los errores en los componentes de la aplicación como métodos inexistentes que el compilador no captura. elegimos Verifier desde el menú Tools. elegimos Deploy Application. Cuando se complete la generación del SQL. • Pulsamos Return • Nos aseguramos de que las cajas Create table on deploy y Delete table on Deploy están marcadas. Se mostrará una caja de diálogo Deploy BonusApp. Esta caja crea un fichero JAR con toda la información de despliegue necesaria para una aplicación solitaria. • Ahora pulsamos Generate SQL .war al fichero WAR durante su creacción.Santiago Chile 49 . Nota: En la versión 1. • • • Seleccionamos el método findByPrimaryKey en la caja EJB method. pulsamos OK. Debería ser SELECT "socsec" FROM "BonusBeanTable" WHERE "socsec"=?. Este ejemplo usa un servlet y una página HTML por lo que no debe estár marcada. Verificar: • • • Con 2BeansApp seleccionado. • Pulsamos Next . El único momento en que debemos chequear esta caja es cuando usamos persistencia controlada por el bean o desplegamos una aplicación solitaria para el programa cliente. • Verificar que la selección de Target Server es un host local o el nombre de un host donde se está ejecutando el servidor J2EE.www. Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicación. Verificar y Desplegar la Aplicación J2EE Antes de desplegar la aplicación. Nota: Si obtenemos un error Save cuando verificamos o desplegamos. Es un error menor y la aplicación J2EE se despliega sin problemas.ciisa. El interrogante representa el parámetro pasado para el método findByPrimaryKey. debemos parar todo y rearrancar el servidor y las herramientas. Nota: No marcamos la caja "Return Client Jar". Esto significa que la herramienta DeployTool no puso la extensión .cl . arrancamos de nuevo la base de datos como se describe en Arrancar la Plataforma y las Herramientas.

Se mostrará una caja de diálogo que mostrará el estado de la operación de despliegue. Cuando se haya completado. y pulsamos la tecla Return. Nos aseguramos de que el nombre Context Root muestra BonusRoot. Pulsamos Finish para empezar el despliegue.• • • • • Nos aseguramos de que los nombres JNDI muestran calcs para CalcBean y bonus para BonusBean.*6322102.Santiago Chile 50 .html apuntamos nuestros navegador a http://localhost:8000/BonusRoot/bonus. Cuando esto suceda pulsamos OK Ejecutar la Aplicación J2EE El servidor web se ejecuta por defecto en el puerto 8000.html. como se ve en la siguiente figura. Si no es así. las tres barras de la izquierda se habrán sombreado completamente. tecleamos los nombres JNDI nosotros mismos. que es donde DeployTool puso el fichero HMTL.html y cambiamos el multiplicador por 2. veremos esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Duplicate primary key Huérfanos 835 piso 20 oficina 2003. Si no es así.cl . pero usamos el mismo número de la seguridad social. Para abrir la página bonus. y pulsamos el botón Submit.ciisa. Pulsamos Next.www.0 Si volvemos al código de bonus. Fax: 6322529 . Pulsamos Next . lo tecleamos nosotros mismos y pulsamos la tecla Return. Rellenamos un número de la seguridad social y un múltiplicador. Fonos: * 6322497. BonusServlet procesa nuestros datos y devuelve una página HTML con el bono calculado Bonus Calculation Soc Sec retrieved: 777777777 Bonus Amount Retrieved: 200.

No hay métodos HttpServlet como init .www.Capitulo IV .ciisa.*" %> <%@ page import="javax.Tecnología JavaServer Pages™ (JSP) La tecnología JavaServer Pages™ (JSP) nos permite poner segmentos de código servlet directamente dentro de una página HTML estática. %> <%! Integer integerMult. o doPost. <HTML> <HEAD> <TITLE>Bonus Calculation</TITLE> </HEAD> <%-.Comment Scriptlet for import statements <%@ indicates a jsp directive --%> <%@ page import="javax.rmi. carga y ejecuta un servlet en segundo plano para ejecutar los segmentos de código servlet y devolver una página HTML o imprimir un informe XML. el código que normalmente iría en estos métodos está directamente embebido en la página JSP usando etiequetas JSP. Observa que las etiquetas JSP no pueden estar anidadas.getParameter("MULTIPLIER").getParameter("SOCSEC"). Por ejemplo. compila. bonus = 100.jsp ) es equivalente al BonusServlet del capitulo anterior. Fonos: * 6322497.naming. Este capitulo modifica el fichero WAR del capitulo anterior para usar una página JSP en lugar de BonusServlet.00. Huérfanos 835 piso 20 oficina 2003. En su lugar. <% indicates a jsp scriptlet --%> <%! String strMult.intValue(). socsec = request. convert string to Integer to int for bonus calculation.PortableRemoteObject" %> <%@ page import="Beans. Fax: 6322529 . se ejecuta el código del servlet y el servidor de aplicaciones crea.Comment Scriptlet to look up session Bean --%> <% InitialContext ctx = new InitialContext(). Cuando el navegador carga una página JSP. %> <%-. multiplier = integerMult. Crear la Página JSP Una página JSP se parece a una página HTML con segmentos de código servlet embebidos entre varias etiquetas de apertura ( <% ) y cierre (%> ) JSP. no podemos anidar una etiqueta de comentario JSP con una etiqueta scriptlet JSP.Santiago Chile 51 . Después del código podremos ver una descripción detallada de las etiquetas JSP. doGet. socsec. La siguiente página JAP ( Bonus.Comment Scriptlet to get the parameters.*6322102. %> <%! int multiplier. %> <%! double bonus.*" %> <%-. and declare/initialize bonus variable. integerMult = new Integer(strMult). %> <% strMult = request.cl .

ejb.calcBonus( multiplier. Fonos: * 6322497.Comment Scriptlet to close try and catch block --%> <% } %> <%-. call calcBonus method. Bonus theBonus = theCalculation.www.ciisa.*6322102.Comment Scriptlet to create session Bean.Comment Scriptlet to catch DuplicateKeyException --%> <% } catch (javax.getBonus() %> <P> <%-. %> <%-.getMessage().getSocSec() %> <P> Bonus Amount retrieved: <%= record.Santiago Chile 52 . CalcHome homecalc = (CalcHome) PortableRemoteObject.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 HTML code to close HTML body and page --%> </BODY> </HTML> Huérfanos 835 piso 20 oficina 2003. %> <%-.class). %> <%-. --%> <H1>Bonus Calculation</H1> Social security number retrieved: <%= record. bonus. and retrieve a database record by the social security number (primary key) --%> <% try { Calc theCalculation = homecalc. CalcHome. Bonus record = theCalculation.narrow( objref. Fax: 6322529 .cl . socsec).create().DuplicateKeyException e) { String message = e.Comment HTML code to display retrieved data on returned HTML page.Object objref = ctx.getRecord(socsec).lookup("calcs").

%> <%! double bonus. <%! double bonus.*6322102.*" %> Declaraciones Las declaraciones JSP nos permiten configurar variables para su uso posterior en expresiones o scriptlets. Por ejemplo.naming. . Las directivas están encerradas entre etiquetas de directiva <%@ y %>. Huérfanos 835 piso 20 oficina 2003. Los comentarios JSP son similares a los comentarios HTML excepto en que empiezan con <%-.ciisa.cl . Fax: 6322529 . <%! String strMult. Nota: Hemos visto que poner dos puntos (:) en un comentario JSP como en <%-.*" %> <%@ page import="javax. socsec = request. Fonos: * 6322497. También podemos declarar variables dentro de expresiones o scriptlets en el momento de usarlas.rmi. <% strMult = request. %> <%! int multiplier. no hay concepto de variables de ejemplar.www. Este scriptlet usa las variables declaradas en las directivas descritas arriba. multiplier = integerMult. String text. . %> <%! Integer integerMult. <HTML> <HEAD> <TITLE>Bonus Calculation</TITLE> </HEAD> <%-. El codigo embebido se inserta directamente en el servlet generado que se ejecuta cuando se pide la página. no tenemos que declarar variables de ejemplar para usar en más de una expresión o scriptlet.getParameter("SOCSEC"). Los Scriptlets van encerradas entre etiquetas <% y %>. que es como empiezan en HTML.getParameter("MULTIPLIER"). Los comentarios HTML se envían al navegador web del cliente donde aparezcan como parte de la página HTML. creaba un error en tiempo de ejecución que desaparecía cuando eliminamos los dos puntos. El ámbito es toda la página JSP. socsec. Podemos tener varias declaraciones. Las declaraciones van encerradas entre etiquetas de declaración <%! y %>. y los comentarios JSP son eliminados y no aparecen en el HTML generado.Comment Scriptlet for import statements <%@ indicates a jsp directive --%> Directivas Las directivas JSP son instrucciones procesadas por el motor JSP cuando la página JSP se traduce a un servlet.intValue(). %> Scriptlets Los scriptlets JSP nos permiten embeber segmentos de código java dentro de una página JSP.jsp muestran un HTML normal seguido por un comentario JSP.Santiago Chile 53 . Podemos usar comentarios JSP o HTML en una página HTML. integerMult = new Integer(strMult). %> . Las directivas usadas en este ejemplo le dicen al motor JSP que incluya ciertos paquetes y clases. <%@ page import="javax.PortableRemoteObject" %> <%@ page import="Beans.en lugar de <!--.Comment: Scriptlet for import statements .Comentarios Las primeras siete líneas de Bonus. Es decir.

www.*6322102. Huérfanos 835 piso 20 oficina 2003.00. En este ejemplo.bonus = 100. una expresión recupera el número de la seguridad social desde el bean de entidad Bonus y lo pone en la página JSP. jsp:setProperty. Este ejemplo usa la variable predefinida request.Santiago Chile 54 . pero las veremos en la siguiente lección.intValue().ciisa. De igual forma. response.getParameter("MULTIPLIER").getSocSec() %> <P> Bonus Amount retrieved: <%= record. <% strMult = request. jsp:plugin descarga automáticamente el Plug-In Java al cliente para ejecutar applet en la plataforma Java adecuada. socsec = request. request. out es un objeto PrintWriter.getBonus() %> <P> Etiquetas Especificas de JSP La especificación JavaServer Pages 1. Fax: 6322529 . <H1>Bonus Calculation</H1> Social security number retrieved: <%= record. multiplier = integerMult.1 son las siguientes: jsp:forward y jsp:include para instruir al motor JSP que pase de la página actual a otra página JSP.00. Las etiquetas específicas JSP definidas en la especificación 1.getParameter("SOCSEC"). integerMult = new Integer(strMult). out .cl . jsp:useBean. que es un objeto HttpServletRequest.1 define etiquetas específicas de JSP que nos permiten extender la implementación JSP con nuevas características y ocultar mucha complejidad a los diseñadores visuales que necesitan buscar la página JSP y modificarla. bonus = 100. response es un objeto HttpServletResponse. excepto que no las declaramos. %> Expresiones La expresiones JSP nos permiten recuperar dinámicamente o calcular valores a insertar directamente en la página JSP. e in es un objeto BufferedReader. e in. Las variables predefinidas se usan en los scriptlets de la misma forma que se usan en los servelts. Fonos: * 6322497. El ejemplo JSP de esta lección no usa ninguna de estas etiquetas específicas. jsp:getProperty nos permiten embeber y utilizar tecnología JavaBeans en páginas JSP. %> Variables Predefinidas Un scriptlet puede usar las siguientes variables predefinidas: session.

tecleamos esto desde el directorio J2EE: Unix j2sdkee1.*6322102.2. Fax: 6322529 .1/bin/deploytool j2sdkee1.2.1/bin/j2ee -verbose j2sdkee1.html es hacer que el parametro ACTION del formulario HTML invoque a Bonus. y la base de datos Cloudscape.Modificar bonus.jsp en lugar de a BonusServlet . <HTML> <BODY BGCOLOR = "WHITE"> <BLOCKQUOTE> <H3>Bonus Calculation</H3> <FORM METHOD="GET" ACTION="Bonus. tecleamos los siguientes comandos: j2ee -verbose deploytool cloudscape –start Si esto no funciona. En diferentes ventanas. Fonos: * 6322497.1\bin\j2ee -verbose j2sdkee1.ciisa.1\bin\cloudscape -start Huérfanos 835 piso 20 oficina 2003.cl .1/bin/cloudscape -start Windows j2sdkee1.1\bin\deploytool j2sdkee1.2. la herramienta Deploy.2.html El único cambio que necesitamos hacer a bonus.www.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.2.2. necesitamos arrancar el servidor J2EE.Santiago Chile 55 .

podemos corregirlo manualmente copiándolos en las localizaciones correctas. War File General Properties : Nota: Parece que hay un bug en la herramienta Deploy. Propiedades generales del Componente: • Ponemos Bonus.Eliminar el Fichero WAR Como se ha añadido una página JSP al componente Web. • Ponemos BonusJSP como nombre de display.html.*6322102.jsp.Santiago Chile 56 .www.2/public_html/JSPRoot/bonus.html • Pulsamos Finish . Si esto sucede. • Seleccionamos Delete desde el menú Edit. Propiedades Generales del Fichero War : • Pulsamos Next. Debemos asegurarnos de añadir primero Bonus. Así es como deben estar después del despliegue: ~/j2sdkee1.jsp seguido de bonus. Elegir el tipo de Componente: .jsp como nombre de fichero JSP. Fonos: * 6322497.html donde debería ir Bonus. Ventana Inspecting: • Seleccionamos Web Context • Especificamos JSPRoot.html ~/j2sdkee1.jsp donde debería ir bonus. • Pulsamos Next • Vamos al directorio ClientCode y añadimos bonus.html. • Seleccionamos BonusWar para que se ilumine. tenemos que borrar el fichero WAR de las lecciones anteriores y crear uno nuevo con la página JSP. Crear el Nuevo Fichero WAR Menú File: • Seleccionamos New Web Component Introduction: • Leemos y pulsamos Next .jsp y Bonus. Fax: 6322529 .html.cl . Huérfanos 835 piso 20 oficina 2003.ciisa. Si añadimos primero bonus. • Pulsamos Next.2/public_html/JSPRoot/WEB-INF/classes/Bonus. la herramienta Deploy pone bonus. • Pulsamos Finish . • Seleccionamos Describe a JSP. Local Applications: • Pulsar el icono 2BeansApp para poder ver los componentes de nuestra aplicación. • Pulsamos Add • Vamos al directorio ClientCode y añadimos Bonus.jsp • Especificamos BonusWar para el nombre de display.

Huérfanos 835 piso 20 oficina 2003. como se ve en la siguiente figura. El verificador mostrará los errores en los componentes de la aplicación como métodos inexistentes que el compilador no captura. Si no es así. Cuando esto suceda pulsamos OK. pulsamos OK. las tres barras de la izquierda se habrán sombreado completamente. El único momento en que debemos chequear esta caja es cuando usamos persistencia controlada por el bean o desplegamos una aplicación solitaria para el programa cliente. Nos aseguramos de que los nombres JNDI muestran calcs para CalcBean y bonus para BonusBean. elegimos Verifier desde el menú Tools. Pulsamos Finish para empezar el despliegue. Se mostrará una caja de diálogo Deploy BonusApp. Fax: 6322529 . Desplegar: • • Desde el menú Tools.1 del software podríamos obtener un error tests app.Santiago Chile 57 . Es un error menor y la aplicación J2EE se despliega sin problemas.ciisa. La ventana debería decir que no hay ningún fallo. Esta caja crea un fichero JAR con toda la información de despliegue necesaria para una aplicación solitaria.war al fichero WAR durante su creacción.cl . Verificar: • • • Con 2BeansApp seleccionado. y pulsamos la tecla Return. Pulsamos Next.WebURI.www. Nota: En la versión 1.2. tecleamos los nombres JNDI nosotros mismos. Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicación. es una buena idea ejecutar el verificador. Verificar que la selección de Target Server es un host local o el nombre de un host donde se está ejecutando el servidor J2EE Nota: No marcamos la caja "Return Client Jar".Verificar y Desplegar la Aplicación J2EE Antes de desplegar la aplicación. • • • • • • Pulsamos Next . Si no es así. Cuando se haya completado. elegimos Deploy Application. Nos aseguramos de que el nombre Context Root muestra JSPRoot. Fonos: * 6322497. Se mostrará una caja de diálogo que mostrará el estado de la operación de despliegue.*6322102. Esto significa que la herramienta DeployTool no puso la extensión . Pulsamos Next . lo tecleamos nosotros mismos y pulsamos la tecla Return. En el diálogo que aparece. Este ejemplo usa un servlet y una página HTML por lo que no debe estár marcada.

html y public_html/JSPRoot/WEBINF/classes/Bonus.jsp procesa nuestros datos y devuelve una página HTML con el bono calculado.html. View. veremos algo similar a esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Error: Duplicate primary key • • Capitulo V .Ejecutar la Aplicación J2EE El servidor web se ejecuta por defecto en el puerto 8000. y bonus. que es lo opuesto a donde realmente pertenecen. MVC es un patrón de diseño que consiste en tres tipos Huérfanos 835 piso 20 oficina 2003. Fonos: * 6322497.jsp. que es dónde la herramienta de despliegue puso el fichero HTML. Rellenamos un número de la seguridad social y un multiplicador.cl .Santiago Chile 58 . Pulsamos el botón Submit. Manualmente los copiamos en sus localizaciones correctas como sigue public_html/JSPRoot/bonus. Para abrir la página bonus.html bajo public_html/JSPRoot/WEB-INF/classes. Nota: La Herramienta Deploy pone Bonus. Controller (MVC)".ciisa.jsp bajo public_html/JSPRoot . Fax: 6322529 .www. Bonus Calculation Social Security number retrieved: 777777777 Bonus Amount Retrieved: 200.Tecnología JavaBeans Podemos usar la tecnología JavaBeans™ para poner un JavaBean entre una página JSP y el bean de sesión CalcBean para obtener una mejor separación "Model.*6322102.html apuntamos nuestro navegador a http://localhost:8000/JSPRoot/bonus.0 Si hemos suministrado dos veces el mismo número de la seguridad social. Bonus.

Los beans de entidad y de sesión ( BonusBean y CalcBean ) son los objetos de la aplicación o Modelo.www. el interface de usuario de la aplicación consiste en una página HTML con un formulario HTML. La lección sobre Tecnología JSP se configuró para que las páginas HTML y JSP proporcionaran la presentación en pantalla (Vista) y manejar lo que sucedia cuando el usuario interactúa con los datos (Controlador). Una aplicación que usa patrones de diseño es mucho más sencilla de actualizar. y etiquetas específicas JSP para interactúar con el JavaBean. Otra forma de crear el interface de usuario es con una página JSP que incluya el formulario HTML. mantener y manejar. se muestra el formulario HTML y se ejecutan los escriptlets y las etiquetas especificas JSP para interactuar con el JavaBean. un JavaBean para manejar lo que sucede cuando el usuario interactúa con la vista (Controlador).de objetos.ciisa. la pantalla se parecerá a la de la siguiente figura Huérfanos 835 piso 20 oficina 2003. Separando el Controlador de la Vista permite al JavaBean servir como una envoltura para el bean de sesión y ofrece un ejemplo mucho más claro de la separación MVC.Santiago Chile 59 . Fax: 6322529 . Sobre el Ejemplo En la Lección anterior.cl . Esta lección usa una página JSP para la presentación en pantalla (View). El Modelo proporciona la lógica de negocio de la aplicacón.*6322102. Fonos: * 6322497. y los beans de entidad y de sesión para los objetos de aplicación (Modelo). scriptlets JSP. Un patrón de diseño describe un problema recurrente y sus soluciones cuando la solución no es siempre exactamente la misma para cada recurrencia. El formulario llama a la página JSP cuando el usuario pulsa el botón Submit de la página HTML. Cuando se carga la página JSP. la Vista es la presentación en pantalla. Como todavía no se han suministrado datos. y el Controlador es un objeto que maneja lo que sucede cuando el usuario interactúa con la Vista.

se vuelve a mostrar el formulario HTML.ciisa.cl . La pantalla se parecería algo a la de la siguiente figura. y se ejecutan de nuevo los scriptlets y las etiquetas especificas JSP con los datos suministrados.jsp se llama a sí mismo de forma recursiva. Si el usuario introduce el mismo número de la seguridad social. se devuelve un error de clave duplicada y se muestra sobre la página JSP como se muestra en la siguiente figura: Huérfanos 835 piso 20 oficina 2003. Fonos: * 6322497. Esto es porque el parámetro ACTION del formulario HTML de bonus. Fax: 6322529 .Santiago Chile 60 .*6322102.Cuando el usuario introduce algún dato y pulsa el botón Submit.www.

ssec.Crear bonus. La primera parte del fichero contiene el código HTML para crear el formulario.*6322102. %> <% sMult = request.getParameter("MULTIPLIER"). El código para pasar los datos del formulario HTML al JavaBean está en la segunda parte del fichero.www. %> <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"/> Huérfanos 835 piso 20 oficina 2003. Fax: 6322529 .ciisa.jsp es bastante sencillo poque el código que busca el bean de sesión y calcula el bono está ahora en el JavaBean.cl .Santiago Chile 61 . Abajo podemos ver el fichero bonus. ssec = request.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. Fonos: * 6322497.getParameter("SOCSEC").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 El código de bonus.

<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. Fonos: * 6322497.*6322102. La primera línea 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. <%! String sMult. <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. %> Pasar los Datos al JavaBean Las siguientes etiquetas HTML configuran dos propiedades del JavaBean. %> <% sMult = request. ssec. ssec = request. Recuperar los Datos desde el JavaBean Recuperar los datos desde el JavaBean es similar a enviárselos. <jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/> <jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/> La expresión value="<%=ssec%>" envía el dato contenido en la variable ssec al campo socsec del JavaBean. El parámetro id define un alias para usarlo como referencia al JavaBean.www.getParameter("MULTIPLIER"). Usamos la etiqueta jsp:getProperty e indicamos la propiedad (campo privado) cuyo dato queremos obtener. y el parámetro class especifica la clase JavaBean. En este ejemplo el id es jbonus y el class es JBonusBean. Una propiedad es un campo privado de la clase JavaBean.Santiago Chile 62 . y el número de la seguridad social en la variable ssec String. La segunda línea realiza una operación similar para el campo socsec de la clase JBonusBean.getParameter("SOCSEC"). Fax: 6322529 . El multiplicador se almacena en la variable sMult String.ciisa. La siguiente etiqueta getProperty obtiene el dato almacenado en el campo privado socsec de la clase JBonusBean (con el alias jbonus id ). Huérfanos 835 piso 20 oficina 2003.cl .

Huérfanos 835 piso 20 oficina 2003.printStackTrace(). En la sección Crear bonus. <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™. CalcHome homecalc. Pero para ser un bean. Fonos: * 6322497.cl .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. Aquí tenemos la clase JBonusBean completa.class).jsp. Como los Beans cumplen la especifiación JavaBean. import javax. } catch (javax. Esto es posible porque la clase JBonusBean sigue las convenciones de nombrado y diseño de JavaBeans.*6322102.www. } } public double getBonusAmt() { if(strMult != null){ Integer integerMult = new Integer(strMult). pueden ser accedidos y manejados por otros programas y herramientas que cumplan las mismas convenciones. private double bonusAmt. se utilizarón etiquetas HTML y scriptlets JSP para obtener y seleccionar los datos privados de la clase JBonusBean.rmi. Fax: 6322529 .lookup("calcs"). una clase JavaBean debe seguir un conjunto de sencillas convenciones de nombres y diseño explicados en la especificación JavaBeans. CalcHome. homecalc = (CalcHome) PortableRemoteObject.PortableRemoteObject. import Beans. public JBonusBean() { try{ InitialContext ctx = new InitialContext().naming. socsec.NamingException e) { e.ciisa.Santiago Chile 63 .*. public class JBonusBean { private String strMult. Esta sección describe el código de JBonusBean y nos ofrece una sencilla presentación de la tecnología JavaBeans cuando se usa con páginas JSP.narrow( objref.*.naming. import javax. message. Object objref = ctx.

printStackTrace(). } catch (javax. this. } public void setStrMult(String strMult) { this. } public String getSocsec(){ return this.*6322102. etc.".00. } return this. Fax: 6322529 .bonusAmt. } else { this.getBonus(). Las propiedades realmente son campos privados de la clase que siempre deberían ser privados y sólo accesibles a través de métodos set y get.getSocSec(). Fonos: * 6322497.create().Santiago Chile 64 .message = "None. try { double bonus = 100.socsec.getRecord( socsec).intValue(). o utilizarse para algún cálculo. } public void setSocsec(String socsec) { this.getMessage(). Los datos podrían hacer cosas como definir la apariencia o el comportamiento del JavaBean. bonus.ejb.CreateException e) { e. return this. } } Propiedades del Bean Las propiedades definen los datos que un JavaBean pone a disposición de otros programas o herramientas a través de métodos get o set. socsec). Bonus theBonus = theCalculation. socsec = record.socsec = socsec.DuplicateKeyException e) { message = e. Bonus record = theCalculation.bonusAmt = 0.rmi.strMult = strMult.ejb.int multiplier = integerMult. } public String getStrMult(){ return this.www. } catch (javax. } catch (java.strMult.calcBonus( multiplier.bonusAmt.ciisa. } } public String getMessage(){ return this. Huérfanos 835 piso 20 oficina 2003.message.RemoteException e) { e. bonusAmt = record. Calc theCalculation = homecalc.printStackTrace().cl .

} } Métodos Set JBonusBean tiene dos métodos set (métodos precedidos por la palabra set). el nombre del método es setSocsec.ciisa. los valores usados para las propiedades socsec y strMult vienen de las etiquetas setProperty name de la página JSP. para seleccionar el campo privado socsec. public void setSocsec(String socsec) { this. CalcHome. message. Mientras que los nombres de campos por convención empiezan siempre con una letra minúscula. Object objref = ctx. Los dos métodos set son setSocsec y setStrMult para seleccionar los campos privados socsec y strMult (propiedades JavaBean) . el nombre de método consiste en la palabra set y el nombre de la propiedad. homecalc = (CalcHome) PortableRemoteObject. los métodos set<property> siguen las convenciones de nombrado para que el servidor J2EE pueda mapear las etiquetas setProperty name del fichero JSP a los métodos set<property> correctos para pasar los datos desde la página JSP al JavaBean. la segunda palabra de un nombre de método siempre empieza con una máyuscula.Santiago Chile 65 .naming.lookup("calcs"). socsec.socsec = socsec.printStackTrace(). Fax: 6322529 .*6322102. Huérfanos 835 piso 20 oficina 2003. El servidor J2EE usa la información suministrada en la siguiente etiqueta setProperty name para localizar el correspondiente método 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. El servidor J2EE mapea la mayúscula de Socsec en el nombre del método a la minúscula socsec del campo.www. public JBonusBean() { try{ InitialContext ctx = new InitialContext().narrow( objref. Constructor El constructor JBonusBean busca el bean de sesión. } catch (javax. private double bonusAmt. Por eso. Con los métodos set.El siguiente segmento de código muestra las propiedades privadas de la clase JBonusBean. Estos métodos seleccionan propiedades (campos privados) con valores especificados. Esta clase tiene un correspondiente método get<property> para cada campo y sus correspondientes métodos set<property> para los campos strMult y socsec. El nombre de la propiedad es el nombre de uno de los campos privados de JBonusBean. Los métodos set no tienen valor de retorno y tienen un argumento del tipo apropiado.NamingException e) { e.cl . En este ejemplo.class). public class JBonusBean { private String strMult. Fonos: * 6322497.

el valor de la propiedad strMult pasada a JBonusBean es null.Santiago Chile 66 . por eso podríamos observar que aunque hay una propiedad en JBonusBean para el multiplicador (el campo strMult).getRecord( Huérfanos 835 piso 20 oficina 2003. y strMult (propiedades JavaBean). getMessage.calcBonus( multiplier.create(). Cuando la página JSP se carga por primera vez. En este ejemplo.cl . el usuario final no ha suministrado ningún dato. Calc theCalculation = homecalc.www. La página JSP recupera los datos de las propiedades de JBonusBean usando las siguientes etiquetas getProperty name.ciisa. los valores usados para seleccionar los campos bonusAmt y message vienen desde el método getBonusAmt. En este caso.} public void setStrMult(String strMult) { this. Bonus theBonus = theCalculation. lo que resulta en un multiplicador nulo y un valor nulo de bonusAmt. Los métodos Get siempre tienen un valor de retorno y no tienen argumentos.intValue(). Ocurre un error de servidor cuando la página JSP obtiene e intenta mostrar el valor null de bonusAmt. bonus.bonusAmt para evitar un error en tiempo de ejecución del servidor J2EE.00.*6322102. Fax: 6322529 . pero todas las etiquetas y scriptlets de la página son ejecutados de cualquier forma. Los métodos Get obtienen y devuelven un valor de propiedad (valores de campos privados). getSocsec. public double getBonusAmt() { if(strMult != null){ Integer integerMult = new Integer(strMult). message . } Métodos Get JBonusBean tiene cuatro métodos get (métodos precedidos por la palabra get ). Los cuatro métodos get son getBonusAmt. devuelve this. 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 métodos Get siguen las mismas convenciones de nombres que los métodos Set por eso la página JSP puede recuperar los datos del JBonusBean. int multiplier = integerMult. Bonus record = theCalculation. Para evitar este error. Podríamos observar que aunque el método getBonusAmt seleccciona valores de propiedades. socsec . socsec). El método getBonusAmt usa una sentencia if-else para manejar el caso cuando no se suministra ningún valor strMult.strMult = strMult. y getStrMult para devolver datos desde los campos privados bonusAmt. realmente no necesita devolver ningún valor en este ejemplo. try { double bonus = 100. La página JSP sólo recupera los valores que le interesan. este valor no es recuperado por la página JSP. Fonos: * 6322497. bonusAmt se selecciona a cero en el caso de que se reciba un valor null desde la página JSP.

bonusAmt = record.message = "None. } else { this. Fonos: * 6322497. la herramienta Deploy.". socsec = record.1\bin\deploytool Huérfanos 835 piso 20 oficina 2003. } } public String getMessage(){ return this.socsec = socsec.Santiago Chile 67 .www. } public String getSocsec(){ return this.getBonus().CreateException e) { e.ejb. } catch (javax. tecleamos esto desde el directorio J2EE: Unix j2sdkee1.DuplicateKeyException e) { message = e.2.strMult.ejb. } Arrancar la Plataforma y las Herramientas Para ejecutar este ejemplo. tecleamos los siguientes comandos: j2ee -verbose deploytool cloudscape -start Si esto no funciona. return this.getMessage().strMult = strMult.1/bin/deploytool j2sdkee1.getSocSec().printStackTrace(). } public void setStrMult(String strMult) { this.2. } return this.rmi. } catch (java.socsec.printStackTrace().2. y la base de datos Cloudscape. } public String getStrMult(){ return this. Fax: 6322529 .2.cl .socsec).bonusAmt.bonusAmt.message.bonusAmt = 0. necesitamos arrancar el servidor J2EE.*6322102. En diferentes ventanas.1/bin/j2ee -verbose j2sdkee1.ciisa.2. } public void setSocsec(String socsec) { this.1\bin\j2ee -verbose j2sdkee1.RemoteException e) { e. this. } catch (javax.1/bin/cloudscape -start Windows j2sdkee1.

Santiago Chile 68 .www. • Pulsamos Next. Huérfanos 835 piso 20 oficina 2003.cl . • Seleccionamos BonusWar para que se ilumine.1\bin\cloudscape -start Eliminar el Fichero WAR Como se ha añadido una página JSP al componente Web. Propiedades Generales del Fichero War : • Pulsamos Next. • Seleccionamos Delete desde el menú Edit. El verificador mostrará los errores en los componentes de la aplicación como métodos inexistentes que el compilador no captura. Verificar y Desplegar la Aplicación J2EE Antes de desplegar la aplicación. Ventana Inspecting: • Seleccionamos Web Context • Especificamos JSPRoot.j2sdkee1.jsp como nombre de fichero JSP. • Pulsamos Add • Vamos al directorio ClientCode y añadimos Bonus. tenemos que borrar el fichero WAR de las lecciones anteriores y crear uno nuevo con la página JSP.2. Elegir el tipo de Componente: . Fonos: * 6322497. • Pulsamos Finish . Propiedades generales del Componente: • Ponemos Bonus. • Pulsamos Next • Vamos al directorio ClientCode y añadimos JBonusBean. War File General Properties : • Especificamos BonusWar para el nombre de display.jsp. es una buena idea ejecutar el verificador. Local Applications: • Pulsar el icono 2BeansApp para poder ver los componentes de nuestra aplicación. Crear el Nuevo Fichero WAR Menú File: • Seleccionamos New Web Component Introduction: • Leemos y pulsamos Next .ciisa. • Ponemos BonusJSP como nombre de display. • Seleccionamos Describe a JSP.*6322102.class • Pulsamos Finish . Fax: 6322529 .

Fonos: * 6322497. como se ve en la siguiente figura. Si no es así.cl . Se mostrará una caja de diálogo que mostrará el estado de la operación de despliegue. En el diálogo que aparece. Pulsamos Next. lo tecleamos nosotros mismos y pulsamos la tecla Return.Santiago Chile 69 . Huérfanos 835 piso 20 oficina 2003.Verificar: • • • Con 2BeansApp seleccionado. Nos aseguramos de que el nombre Context Root muestra JSPRoot. elegimos Deploy Application. Esto significa que la herramienta DeployTool no puso la extensión . Es un error menor y la aplicación J2EE se despliega sin problemas. Desplegar: • • Desde el menú Tools. Pulsamos Next . Verificar que la selección de Target Server es un host local o el nombre de un host donde se está ejecutando el servidor J2EE.*6322102. tecleamos los nombres JNDI nosotros mismos. Nos aseguramos de que los nombres JNDI muestran calcs para CalcBean y bonus para BonusBean. Cuando esto suceda pulsamos OK. Se mostrará una caja de diálogo Deploy BonusApp. Si no es así. • • • • • • Pulsamos Next . La ventana debería decir que no hay ningún fallo.1 del software podríamos obtener un error tests app. Esta caja crea un fichero JAR con toda la información de despliegue necesaria para una aplicación solitaria. Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicación. pulsamos OK. Fax: 6322529 . El único momento en que debemos chequear esta caja es cuando usamos persistencia controlada por el bean o desplegamos una aplicación solitaria para el programa cliente. las tres barras de la izquierda se habrán sombreado completamente. Pulsamos Finish para empezar el despliegue. Nota: No marcamos la caja "Return Client Jar". Este ejemplo usa un servlet y una página HTML por lo que no debe estár marcada.WebURI. Cuando se haya completado.war al fichero WAR durante su creacción.2.www. elegimos Verifier desde el menú Tools. Nota: En la versión 1. y pulsamos la tecla Return.ciisa.

html.cl .ciisa. Fonos: * 6322497.Santiago Chile 70 . Pulsamos el botón Submit.html apuntamos nuestro navegador a http://localhost:8000/JSPRoot/bonus. que es dónde la herramienta de despliegue puso el fichero HTML. Para abrir la página bonus.www. • • Rellenamos un número de la seguridad social y un multiplicador.jsp procesa nuestros datos y devuelve una página HTML con el bono calculado. veremos algo similar a esto: Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Error: Duplicate primary key Huérfanos 835 piso 20 oficina 2003.*6322102.Ejecutar la Aplicación J2EE El servidor web se ejecuta por defecto en el puerto 8000. Bonus Calculation Social Security number retrieved: 777777777 Bonus Amount Retrieved: 200. Fax: 6322529 .0 Si hemos suministrado dos veces el mismo número de la seguridad social. Bonus.

Una parte podría pasar los datos XML a través de un programa para traducirlos a HTML y poder ponerlos en la Web. Por ejemplo. y cualquier programa capaz de aplicar estilos XLS o especificaciones DTD a datos XML puede manejar datos que fueron etiquetados de forma inteligente. • Cualquier programa capaz de analizar XML puede chequear etiquetas XML bien-formadas. otra parte podría pasar los datos por una herramienta para producir un inform de stocks. Mismos datos. y un grupo de programas y herramientas independientes de la plataforma para usar los mismos datos en varis formas distintas.Capitulo VI . Diferentes hojas de estilo nos permiten tener diferentes presentaciones dependiendo de cómo se utilice el documento.cl . podemos crear una Definición de Tipo de Documento (DTD) y/o un fichero "eXtensible Style sheet Language (XSL)" para describir cómo queremos que se manejen los datos. si tenemos un fichero de texto que consiste en un pequeño artículo.*6322102. las cabeceras de primer nivel.Añadir 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 leídos y manejados por cualquier programa o herramienta que use los APIs XML. una compañía 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. podemos definir una etiqueta de título XML para que represente el título de un artículo.Santiago Chile 71 . Por ejemplo. las listas bulleteadas. y otra tercera parte podría pasar los datos XML a través de una herramienta para crear una presentación de marketing. Un DTD (también conocido como esquema XML) contiene especificaciones que permiten a otros programa validad la estructura de un fichero XML para asegurarse que los datos están etiquetados de la forma correcta. el autor. Esto significa que podemos tener un documento XML y desde a muchas hojas de estilo o DTDs. diferentes necesidades. Una vez que los datos están representados por etiquetas XML. Por ejemplo. y crear un fichero XSL que mapee la etiqueta de título CML a una etiqueta H1 de HTML para mostrarselo al usuario final. Huérfanos 835 piso 20 oficina 2003. definimos etiquets que represente el título. un DTD para un artículo podría permitir una etiqueta de título. Fonos: * 6322497. un artículo 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. etc.ciisa.www. pero cero o más primeros y segundos niveles de cabeceras. Los programas y herramientas pueden generar ficheros XML que otros programas y herramientas pueden leer y manejar. Estas capaciades tan flexibles y baratas están disponibles a través de etiquetas XML. Definiciones de Tipos de Documentos (DTDs) también conocidos com esquemas XML. Fax: 6322529 . Chequear un documento XML contra un DTD es lo que se conoce como verificación. si un artículo titne dos etiquetas de título. Lo más bonito sobre XML es que el etiquetado está separado de las hojas de estilos y DTD. Por ejemplo. el programa devuelve un error. las cabeceras de segundo nivel. y los APIs XML. Por ejemplo. Esta lección adapta el ejemplo de la Lección anterior para que la clase JavaBeans use los APIs XML para impriir un sencillo informe donde los datos están marcados con etiquetas XML. el texto del artículo. pero el DTD permite sólo una. • Los estilos XSL nos pemiten hacer cosas como el mapeo de XML a HTML. Por ejemplo. Marcar y Manejar Texto Con XML definimos etiquetas de marcas para representar diferentes elementos de datos en un fichero de texto.

0" encoding="UTF-8"?>. se añade un método genXML a la clase JBonusBean para generar el documento XML mostrado abajo. Unicode descomprimido se representa como <?xml version="1. Esta etiqueta es un nodo hijo que se añade al raíz. o un DTD para especificaciones de etiquetas válidas.La versión 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. El prólo no es necesario si sólo va a ser leído por humanos. <?xml version="1.0" /> Huérfanos 835 piso 20 oficina 2003. El conjunto de caracteres Western European y lenguaje Inglés se indica como: <?xml version="1. Otro nombre para este nivel de etiqueta es root. Usa atributos para especificar el número de la seguridad social y el valor del bono ( ssnum y bonusAmt ). Documento Raíz La etiqueta <report> es la primera etiqueta XML de este fichero.cl . Podría haberse llamado <root> o <begin> o cualquier otra cosa. Después de ver las etiquetas y estructura de un documento XML vermos el código que genera este documento XML. y poder hacer que nuestro programa corriga un error si ha desaparecido algún atributo o si los atributos presentes no deberian estar ahí.0" encoding="ISO8859-1"?>.ciisa. Fax: 6322529 . el prólogo también puede incluir información de codificación e información "standalone . Nodos Hijos La etiqueta <bonusCalc> representa el informe de bonos.www. Junto con la información de versión.*6322102. Es la etiqueta XML de más alto nivel y marca el inicio de los datos del documento. Podemos definir un DTD para chequear que las etiquetas bonusCalc tienen los atributos ssnum y bonusAmt. • Información de Codificación: indica el conjunto de caracteres usado en los datos del documento.0" /> </report> Prólogo XML La línea <?xml version="1. <bonusCalc ssnum="777777777" bonusAmt="300. Un fichero XML siempre debe empezar con un prologo que lo identifique como un fichero XML.0"?> <report> <bonusCalc ssnum="777777777" bonusAmt="300. un documento XML podría relacionarse con una hoja de estilo para infomación sobre cómo crear un interface de usuario e HTML. Las etiquetas XML tienen su correspondiente etiqueta final.Santiago Chile 72 . Podemos darle a una etiqueta XML cualquier nombre que queramos. por eso el final de este documento tiene su correspondiente etiqueta </report> para cerrar la pareja. pero es buena idea incluirlo.0"?> es el prólogo XML. el nombre tiene significado en la hoja de estilo y en el DTD porque es donde asignamos especificaciones para las etiquetas por sus nombres. Modificar la Clase JavaBean En esta lección. Fonos: * 6322497. Este ejemplo usa report porque el fichero XML es un informe de bonos. Por ejemplo. • Información Standalone: idnica si este documento usa información de otros ficheros.

Este ejemplo usa etiquetas vacías. Las etiquetas bien-formadas consisten en una etiqueta de apertura y una de cierre como es muestra en el ejemplo de abajo: Etiqueta Vacía: <bonusCalc ssnum="777777777" bonusAmt="300. También necesitamos las clases StringWriter e IOException para escribir datos XML en el terminal. y se cierran con una barra inclinada.xml.tree. Beans. donde xml es la fuente y version="1. Fax: 6322529 .Otras Etiquetas XML Hay varias formas de etiquetar datos XML. manejar errores.0</bonusAmt> </bonusCalc> Los comentarios XML son como las etiquetas de comentario HTML.sun. Esta lección escribe la salida del XML en el terminal para mantener las cosas sencillas. podría crearse para que los datos se encerraran entre etiquetas XML.*6322102.*. El prólogo es un ejemplo de una instrucción de procesamiento. import import import import import import javax. pero necesitaríamos configutrar nuestro navegador para usar el Java Plug-In e incluir un fichero de policía de seguridad que concediera permiso para escribir un fichero. 73 Huérfanos 835 piso 20 oficina 2003.io.StringWriter.*. que son etiquetas que no encierran datos.0"?> También podemos usar instrucciones de procesamiento par ahacer cosas como distinguir entre diferentes versiones de una representación como la versión de alto nivel ejecutivo y la versión de nivel técnico.0" /> Las instrucciones de procesamiento le dan comandos o información a una aplicación que está procesando los datos XML.IOException.Santiago Chile . java. usan atributos para especificar datos. Para generar el fichero XML para esta lección.0" encierra las instrucciones. También podría escribirse en un fichero. El analizador XML chequea todos los datos encerrados por datos que llamados etiquetas bien-formadas. java.ciisa. javax. y escribir el documento en el terminal. Fonos: * 6322497.ElementNode. Código del JavaBean La clase JBonusBean para esta lección tiene sentencias import para crear el documento XML. Las instrucciones de procesamiento tienen el formado <? target instructions?> donde target es el nombre de la aplicación que está haciendo el procesamient.PortableRemoteObject. <!-.io. e instructions encierra la información o comandos para que los procese la aplicación.0" /> Etiquetas bien-formadas: <bonusCalc> <ssnum>"777777777"</ssnum> <bonusAmt>300. necesitamos importar las clases ElementNode y XmlDocument. La siguiente etiqueta vacía de este ejemplo.naming. <?xml version="1.Bonus Report --> <bonusCalc ssnum="777777777" bonusAmt="300.cl .rmi. Debemos observar que el nombre de fuente xml esta reservado para estándar XML. com.www.

*6322102. y añade la raíz al documento. //Create node ElementNode root = (ElementNode) doc. //Add child node to root root. private void genXML(){ Bonus records = null.genXML es llamado desde el método getBonusAmt después de que el proceso se complete en el evento strMult y no sea null . convierte el valor del bono a un string. El nodo hijo epresenta la herencia o árbol. try{ //Get database record records = theCalculation.printStackTrace(). //Retrieve the social security number from record String ssRetrieved = records. recuperar el valor del bono y el número de la seguridad social desde el registro. y los atributos representan el tercer nivel. //Retrieve bonus amount from record double bRetrieved = records. Esta versión de la clase JBonusBean tiene una variable más de ejemplar.import com. //Convert double to string Double bonusObj = new Double(bRetrieved).setAttribute("bonusAmt".XmlDocument. Los bloques try y catch que vienen luego.appendChild(root). //Create child node ElementNode bonusCalc = (ElementNode) doc. } Huérfanos 835 piso 20 oficina 2003.RemoteException e) { e.toString(). Fax: 6322529 .rmi. El nodo raíz represetna el punto de más alto nivel en el árbol del documento y es el punto donde empieza el procesamiento. bonusCalc. El interface remoto del bean de sesión. y añade el número de la seguridad social y el bono al nodo hijo bonusCalc como atributos.getRecord(socsec). } catch (java.www. crea un nodo hijo ( bonusCalc ). Fonos: * 6322497. Calc theCalculation. necesita ser accedido desde los métodos getBonusAmt y genXML.setAttribute("ssnum". bString).getSocSec(). Lo prmero que este método hace es crear un objeto XMLDocument y el nodo raíz.createElement("report"). El método JBonusBean.Santiago Chile 74 .xml. //Create XML document XmlDocument doc = new XmlDocument(). ssRetrieved). //Add attributes to child node bonusCalc.ciisa.cl . obtienen el registro de la base de datos. //Add node to XML document doc. 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 método getRecord del bean de sesión.getBonus().appendChild(bonusCalc).tree.sun. theCalculation.createElement("bonusCalc"). String bString = bonusObj.

cl . El fichero JAR realmente prporciona APIs XML para SAX.www. Podemos crear un DOM desde un fichero XML..out. Fax: 6322529 . Fonos: * 6322497. DOM y J2EE. Huérfanos 835 piso 20 oficina 2003. La siguiente figura muestra una representación simplificada del DOM del ejemplo de esta lección. } catch (IOException ioe) { System.println("cannot write XML"). doc. y escribe el objeto StringWriter al terminal. Los APIs El fichero j2ee.println(out).out. Las llamadas al API en el método genXML crea el DOM y podemos aplicar las llamadas al API para acceder al DOM paa hacer cosas como añadir.write(out). escribe la herencia del documento o árbol al objeto StringWriter.FileNotFoundException fe) { System. } catch (java. el texto XML es independiente de la plataforma y el lenguaje de creacción.jar que viene con nuestra instalación J2EE proporciona APIs para analizar y manipular datos XML.out.Santiago Chile 75 .io.La última parte del método genXML crea un objeto StringWriter.println("Cannot write XML"). o validar el DOM contra un DTD. } El árbol o estructura del documento XML se llama Document Object Model (DOM). Podemos usar cuaquier API que necesitamos como se muestra en la siguiente figura. borrar y editar nodos hijos.ciisa.*6322102. try{ StringWriter out = new StringWriter().. System.

Podemos usar el API DOM para manipular la herencia de los objetos que encapsula.jsp procesa nuestros datos y devuelve una página HTML con el bono calculado. Construir el DOM requiere la lectura de la estructura XML completa y mantener el árbol de objetos en memoria.*6322102. • • Ventana Local Applicatons: Seleccionamos la aplicación 2BeansApp. simplementen podemos actualizar y redesplegar la aplicación. Por esta razón.ciisa.sun y se han utilizado en el ejemplo de esta lección. Bonus. Nota: La aplicación BonusApp de la lección anterior se desinstala automáticamente.JDBC Hasta ahora.www. Capitulo VII . Fonos: * 6322497. El API DOM proporciona una estructura de objetos del tipo árbol relativamente familiar. que es donde la herramietna Deploy puso la página JSP. Menú Tools: Seleccionamos Update and Redeploy Application. Esta lección nos muestra como sobreescribir la persistencia controlada por el contenedor por defecto e implementar la persistencia controlada por el bean. No olvidemos que estos APIs están sujetos a modificaciones.Santiago Chile 76 . Huérfanos 835 piso 20 oficina 2003. Pulsamos el botón Submit.SAX y DOM El API SAX es un mecanismo de acceso serial dirigido por eventos que hace un proceso elemento por elemento. La persistencia controlada por el contenedor es el termino usado para describir la situación donde el contenedor maneja el almacenamiento y la recuperación. los APIs XML J2EE están en el paquete com. El API DOM es ideal para aplicaciones interactivas porque el modelo completo del objeto está presente en la memoria. Esto es porque el contenedor ha estado manejando el almacenamiento y recuperación de los datos a través del bean de entidad. Fax: 6322529 . El servidor web se ejecuta por defecto en el puerto 8000. lo que significa mucho consumo de CPU y de memoria.jsp apuntamos el navegador a http://localhost:8000/JSPRoot/bonus.jsp. • • Rellenamos un número de la seguridad social y un multiplicador. donde el usuario puede acceder a él y modificarlo. la aplicación de ejemplo J2EE ha escrito y leído los datos desde una base de datos Cloudscape subyancente sin que hayamos escrito código SQL. Actualizar y Ejecutar la Aplicación Como todo lo que hemos hecho en esta lección ha sido modificar la clase JBonusBean.cl . Para abrir la página bonus. J2EE El API XML J2EE independiente de la plataforma usa un árbol DOM y proporciona muchos métodos para manipularlo. se tiende a preferir el API SAX para aplicaciones clienteservidor y para filtros de datos que no requieren una representación de los datos en memoria.

y ejbCreate para crear un bean de entidad y pasarle los valores bonus y socsec. ejbFindByPrimaryKey: El contenedor llama a este método cuando un cliente llama al método findByPrimaryKey del interface home del bean. El contexto de entidad lo actualiza dinamicamente el contenedor incluso si muchos clientes llaman al bean de entidad a la vez. El contenedor tenía en cuenta cosas como la creacción de la fila en la tabla de la base de datos. 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. Fonos: * 6322497. el contexto contiene datos actuales para cada llamada. Los únicos métodos con implementaciones eran getBonus para devolver el valor del bono. Huérfanos 835 piso 20 oficina 2003. Sin embargo. lo que significa añadir codigo JDBC™ y SQL. e implementar los métodos vacíos del ejemplo controlado por el contenedor. y asegurarse de que los datos en memoria era consistentes con los datos de la fila de la tabla.*6322102. Esta lección modifica el bean de entidad de la aplicación de ejemplo J2EE para usar persistencia controlada por el bean. ejbCreate: El contenedor llama a este método cuando un cliente llama al método create del interface home del bean. • setEntityContext: El contenedor llama primero a este método para pasar un objeto contexto al bean de entidad. calcBean y getRecord . Hay un método ejbPostCreate por cada método ejbCreate que toma los mismos argumentos que su método create. A los métodos de negocio los llama el cliente y a los métodos del ciclo de vida los llama el contenedor del bean. Ciclo de Vida del Bean La Lección 3 mostraba la clase BonusBean manejada por el contenedor. ejbLoad y ejbStore : El contenedor llama a estos métodos para sincronizar el estado del bean con la base de datos subyacente. en el ejemplo. getSocSec para devolver el número de la seguridad social. ejbPostCreate: El contenedor llama a este método después de que se complete el método ejbCreate.cl . ejbRemove: El contenedor llama a este método cuando un cliente llama al método remove del interface home del bean. CalcBean tiene dos métodos de negocio. Lo podemos dejar en blanco si no necesitamos procesamiento especial.www. ejbPostCreate no tiene valor de retorno. Un bean de sesión o de entidad consiste en métodos de negocio y métodos de ciclo de vida. Un bean de sesión tiene un método setSessionContext correspondiente que realiza una función similar a la del método setEntityContext. Fax: 6322529 .Santiago Chile • • • • • • 77 . Usamos ejbPostCreate para implementar cualquier procesamiento especial que necesitemos hacer después de crear el bean y antes de que esté disponible para el cliente. Sólo los beans de entidad tienen un método unsetEntityContext. el bean tiene un método ejbCreate correspondiente con la misma firma (parámetros y valor de retorno). unsetEntityContext: El contenedor llama a este método después de que se haya llamado a ejbRemove para eliminar el bean de entidad. Tanto CalcBean como BonusBean tienen los siguientes métodos de ciclo de vida. Cuando un cliente selecciona u obtiene los datos de un bean como en el caso de un método get. Con la persistencia controlada por el bean nosotros tenemos que implementar todos estos comportamientos. y BonusBean tiene dos métodos de negocio getBonus y getSocsec. Por cada método find del interface home del bean. Un bean de sesión no tiene el correspondiente método unsetSessionContext.ciisa. Por cada método create en el interface home.La persistencia controlada por el bean es cuando nosotros escribimos métodos de los beans de entidad o de sesión para usar los comandos SQL que le proporcionamos. tiene su correspondiente método ejbFind< type > con la misma firma (parámetros y valor de retorno). La aplicación de ejemplo J2EE para este tutorial no incluye ningún método remove en el interface home.

el contenedor llama al método ejbStore para envíar el objeto a la base de datos y llama a ejbLoad para leerlo de nuevo.Connection.sql.EntityBean. Fonos: * 6322497. import javax. import java.naming. import java.sql. Fax: 6322529 .sql. Lo primero que observaremos es que hay mucho más código que en la versión con persistencia controlada por el contenedor. La interface ResultSet se importa para manejar accesos a filas de datos devueltas por una consulta. Las implementaciones de ejbPassivate podrían incluir cosas como el cierre de conexiones o ficheros usados por el bean.InitialContext. package Beans.ResultSet. Huérfanos 835 piso 20 oficina 2003. La interface PreparedStatement se importa para usarlo como plantilla para crear una petición SQL. • ejbActivate y ejbPassivate: El contenedor llama a estos métodos para activar o desactivar el estado del bean.EntityContext.FinderException. import java. el contenedor llama a ejbLoad para inicializar el bean con los datos desde la base de datos subyacente.rmi. import javax. La activación o desactivación se refieren al intercambio del bean dentro y fuera del almacenamiento temporal para liberar memoria. Sentencias Import Las interfaces InitialContext.ejb. Cuando un cliente llama a un método find.RemoteException.ejb.*6322102. import java.www.sql. DataSource.PreparedStatement.ejb.sql.DataSource. import javax. import javax. Modificar el código de BonusBean Esta sección nos lleva a través del código de BonusBean con persistencia controlada por el bean. que podría ocurrir si un bean dado no ha sido llamado por un cliente desde hace mucho tiempo.Santiago Chile 78 .cl . Las clases FinderException y SQLException se importan para manejar excepciones de búsqueda y accesos a bases de datos.SQLException. y para ejbActivate podría incluir cosas como la reapertura de las mismas conexiones o ficheros.ejb.ciisa. import javax. y Connection se importan para establecer conexiones con la base de datos.CreateException. import java. import javax.

Métodos de Negocio Los métodos de negocio no han cambiado para esta lección excepto en las llamadas a System.Variables de Ejemplar Las variables de ejemplar añadidas en esta lección nos permiten establecer y cerrar conexiones con bases de datos.println("getSocSec"). ejbCreate La firma del método ejbCreate para esta lección lanza RemoteException y SQLException además de CreateException. SQLException es necesaria porque el método ejbCreate proporciona su propio código SQL. Fonos: * 6322497. que también deberíamos especificar cuando añadamos el bean de entidad a la aplicación J2EE usando la herramienta Deploy. que nos permiten ver el orden en que se llaman los métodos de negocio y ciclo de vida durante la ejecución.cl . private PreparedStatement ps = null. y RemoteException es necesaria porque ese método realiza acceso remoto Huérfanos 835 piso 20 oficina 2003. private double bonus.ciisa. } public String getSocSec() { System. return this. En este ejemplo. return this.out. Fax: 6322529 . Después crearemos la tabla BONUS en CloudscapeDB. private String dbName = "java:comp/env/jdbc/BonusDB". El string java:comp/env/jdbc/BonusDB indica el nombre de referencia para el recurso. y durante el despliegue mapearemos jdbc/BonusDB a jdbc/CloudscapeDB . la referencia de recursos es un alias a la base de datos Cloudscape ( CloudscapeDB) donde está almacenada la tabla de datos.println("getBonus").println para que podamos ver en que orden se llaman durante la ejecución.socsec. public double getBonus() { System.Santiago Chile 79 . private InitialContext ic = null. public class BonusBean implements EntityBean { private EntityContext context. private String socsec.out.bonus.out.*6322102. } Métodos de Ciclo de Vida Estos métodos incluyen llamadas a System.out.www.println. private Connection con.

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

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

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

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

sql. String socsec) throws RemoteException. this. el método CalcBean. SQLException. socsec = null. public Bonus calcBonus(int multiplier.*6322102. Fonos: * 6322497. public void ejbPassivate() { System.EntityContext ctx){ System. el contenedor lo desactiva o lo mueve a un almacenamiento temporal donde el contenedor puede rápidamente reactivar el bean en el caso de que algún cliente llame a un método de negocio del bean. CreateException { Bonus theBonus = null. Fax: 6322529 . homebonus = (BonusHome) PortableRemoteObject.cl .println("setEntityContext method").www. ctx = null.lookup("bonus").out. } unsetEntityContext El contenedor llama a este método para poner a null la variable de ejemplar context después de que se haya llamado al método ejbRemove para eliminar el bean. } } Modificar el Código de CalcBean y JBonusBean Como BonusBean proporciona su propio código SQL.out.Santiago Chile 84 . Aquí tenemos la forma de hacer este cambio: public class CalcBean implements SessionBean { BonusHome homebonus.narrow( Huérfanos 835 piso 20 oficina 2003.out. tiene que modificarse para lanzar la excepción java.ejb. Object objref = ctx. double calc = (multiplier*bonus).println("unsetEntityContext method"). Este método selecciona la clave primaria a null para liberar memoria mientras el bean está desactivado. Es necesario porque el método ejbActivate llama al método getPrimarykey sobre la variable de ejemplar context para pasar el bean del estado desactivado al de activado.println("Passivate method"). } setEntityContext El contenedor llama a este método para inicializar la variable de ejemplar context del bean. public void setEntityContext( javax.SQLException. Sólo los beans de entidad tienen un método unsetEntityContext. try { InitialContext ctx = new InitialContext().calcbonus.context = ctx. public void unsetEntityContext(){ System. que crea ejemplares de BonusBean.Cuando un bean no se ha utilizado durante mucho tiempo. double bonus.ciisa.

ejb.intValue(). DuplicateKeyExcpetion es una subclase de CreateException.cl .*6322102. } catch (java. this.bonusAmt. Fonos: * 6322497. Bonus theBonus = theCalculation. Bonus record = theCalculation. return this.objref. this. theCalculation = homecalc.bonusAmt = 0.rmi. bonusAmt = record.create(calc.create(). } genXML().00. this.getMessage().getMessage().getSocSec().getBonus().socsec = "000". por eso será capturada por la sentencia catch (javax.bonusAmt. int multiplier = integerMult.message = "None. socsec).getMessage(). this.message = e.class). socsec). public double getBonusAmt() { if(strMult != null){ Integer integerMult = new Integer(strMult).message = e.bonusAmt = 0. } catch (java.calcBonus( multiplier.bonusAmt = 0.RemoteException e) { this.".CreateExceptione). } catch (Exception NamingException) { NamingException. return this.socsec = "000". } La clase JBonusBean tiene que modificarse para capturar la SQLException lanzada por CalcBean.ciisa.0.SQLException e) { this. socsec = record. Fax: 6322529 .printStackTrace().message = e.sql.www. this. } //Store data in entity Bean theBonus=homebonus. } catch (javax. } else { this. BonusHome.bonusAmt = 0.0.ejb. try { double bonus = 100.0. this.socsec = "000".Santiago Chile 85 . this.getRecord( socsec). return theBonus. } } Crear la Tabla de la Base de Datos Huérfanos 835 piso 20 oficina 2003.CreateException e) { this. bonus.

2.*6322102.connection.bat (Windows/NT).cl .sql y cloudTable.sh (Unix) o cloudTable.jar.2.Santiago Chile 86 .CloudscapeDB= jdbc:rmi://localhost:1099/jdbc:cloudscape: CloudscapeDB\. vamos al directorio Beans y tecleamos los siguiente: Unix: .ij createTable.Como este ejemplo usa persistencia controlada por el bean. bonus decimal(10. y el script cloudTable.jar. la tabla se creaba automáticamente. create table bonus (socsec varchar(9) constraint pk_bonus primary key. Para ejecutar estos scripts.bat rem Creates BONUS table in CloudscapeDB.ciisa. Fax: 6322529 . la tabla de la base de datos se crea con dos scripts: createTable.jar.home= %J2EE_HOME%\cloudscape -classpath %J2EE_HOME%iib\cloudscape\client.www. drop table bonus.sh Windows/NT: . %J2EE_HOME%iib\cloudscape\cloudscape.bat Este fichero se proporciona con los ficheros fuentes de esta leccción.sh rem rem Change this next line to point to *your* rem j2sdkee1. Con persistencia controladda por el contenedor.sql Huérfanos 835 piso 20 oficina 2003. %CLASSPATH% -ms16m -mx32m COM.. Para mantener las cosas sencillas.1 rem rem Everything below goes on one line java -Dij. Para este ejemplo. %J2EE_HOME%iib\cloudscape\RmiJdbc.sh (Unix) o cloudTable.2)).bat createTable.. %J2EE_HOME%iib\cloudscapeiicense./cloudTable.1 installation rem set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.sql va en nuestro directorio ~/J2EE/Beans.system.create=true -Dcloudscape. exit.bat (Windows/NT) va en nuestro directorio ~/J2EE. tenemos que crear la tabla BONUS en la base de datos CloudscapeDB.jar.sql Este fichero se proporciona con los ficheros fuentes de esta leccción.cloudscape. cloudTable. rem cloudTable.tools.\cloudTable. el escript createTable.jar. %J2EE_HOME%iib\cloudscape\ tools. Fonos: * 6322497. rem rem Place this script in ~\J2EE rem To run: cd ~\J2EE\cloudTable.

Santiago Chile 87 .home= $J2EE_HOME/cloudscape -classpath $J2EE_HOME/lib/cloudscape/client. tenemos que borrar 2BeansJar y crear uno nuevo.cloudscape. Pulsamos OK. Fonos: * 6322497. Cambiamos de directorio para que el directorio Beans muestre su contenido.class.sh Este fichero se proporciona con los ficheros fuentes de esta leccción. Si tenemos los beans en ficheros JAR separados.jar: $J2EE_HOME/lib/cloudscape/cloudscape.system.class Pulsamos Add .ij createTable.jar: ${CLASSPATH} -ms16m -mx32m COM.www.class Pulsamos Add . Si tenemos los dos beans en un sólo fichero JAR.cl .CloudscapeDB=jdbc:rmi: //localhost:1099/jdbc:cloudscape:CloudscapeDB\.ciisa.connection.tools.jar: $J2EE_HOME/lib/cloudscape/license.*6322102. y Beans/BonusBean.sql Eliminar el Fichero JAR Tenemos que actualizar el fichero JAR con el nuevo código del Bean.jar: $J2EE_HOME/lib/cloudscape/RmiJdbc. Seleccionamos BonusBean.class.jar: $J2EE_HOME/lib/cloudscape/tools. Estas instrucciones empiezan en el momento de añadir los interfaces y las clases de BonusBean al fichero JAR. Fax: 6322529 . Seleccionamos Bonus. Los pasos para añadir BonusBean son ligeramente diferentes como se describe aquí. Los pasos para añadir CalcBean son los mismos que los de la lección Comunicaciones entre Beans. #!/bin/sh J2EE_HOME=/home/monicap/J2EE/j2sdkee1. create=true -Dcloudscape. EJB JAR : Huérfanos 835 piso 20 oficina 2003.2 java -Dij.class en el display. Beans/BonusHome. Seleccionamos BonusHome. EJB JAR : • • • • • • • • Pulsamos Add (el más cercano a la ventana Contents).class Pulsamos Add .cloudTable. tenemos que borrar el fichero JAR con BonusBean y crear uno nuevo como se describe aquí. Clases Enterprise Bean JAR : • • Nos aseguramos de ver Beans/Bonus.

y Beans.Bonus es el interface Remoto. es una buena idea ejecutar el verificador. bonus a BonusBean .*6322102. La transación se envía justo antes de que los métodos terminen. los tipos primitivos no son válidos como claves primarias.BonusHome es el interface Home. Fax: 6322529 .cl . y jdbc/Cloudscape a jdbc/BonusDB. Nos aseguramos de que Type es javax. Entradas de Entornio: • Pulsamos Next.BonusBean es el nombre de clase. elegimos Verifier desde el menú Tools.ciisa.DataSource. Referencias a Recursos: • Pulsamos Add • Tecleamos jdbc/BonusDB en la primera columna.• Pulsamos Next . Selecciones de Entidad: • • Seleccionamos Bean-managed persistence . • Pulsamos Next . Esto significa que el contenedor arranca una nueva transación antes de ejecutar estos métodos. • En la lista de abajo .sql. Fonos: * 6322497. findByPrimaryKey. La clase de clave primaria es java. Este sencillo bean no usa roles de seguridad. Ventana Inspecting: • Con 2BeansApp seleccionado pulsamos JNDI names. Seguridad: • Pulsamos Next. Este sencillo bean no usa propiedades (entradas de entorno).Santiago Chile 88 . • Pulsamos Entity . Referencias a Beans Enterprise: • Pulsamos Next . marcamos como necesarios create . Observa que la clave primaria tiene que ser un tipo de clase. Pulsamos Next • . Huérfanos 835 piso 20 oficina 2003. Verificar y Desplegar la Aplicación Antes de desplegar la aplicación.www. getBonus y getSocSec. • Introducimos BonusBean como nombre de display.String. El verificador mostrará los errores en los componentes de la aplicación como métodos inexistentes que el compilador no captura. • Pulsamos Next . Beans. debajo de Coded Name. • Pulsamos Next. Revisión de Selecciones: • Pulsamos Finish . General : • Nos aseguramos de que Beans.lang. Control de Transacción : • Seleccionamos Container-managed transactions (si no lo está ya). Verificar: • Con 2BeansApp seleccionado. y Authentication es Container . • Asignamos calcs a CalcBean .

html. elegimos Deploy Application.cl .pulsamos OK. lo tecleamos nosotros mismos y pulsamos la tecla Return. • Cuando se haya completado.ciisa. Pulsamos el botón Submit. • • Rellenamos un número de la seguridad social y un multiplicador. Si no es así. Ejecutar la Aplicación El servidor web se ejecuta por defecto en el puerto 8000. Huérfanos 835 piso 20 oficina 2003. • • Pulsamos Next . La ventana debería decir que no hay ningún fallo. Si no es así. Para abrir la página bonus. Se mostrará una caja de diálogo que mostrará el estado de la operación de despliegue. pulsamos OK. • Verificar que la selección de Target Server es un host local o el nombre de un host donde se está ejecutando el servidor J2EE.Santiago Chile 89 .• En el diálogo que aparece.*6322102. • Pulsamos Next. Es un error menor y la aplicación J2EE se despliega sin problemas. Pulsamos Finish para empezar el despliegue. Fonos: * 6322497. Desplegar: • Desde el menú Tools.html apuntamos nuestro navegador a http://localhost:8000/JSPRoot/bonus. La salida del servidor J2EE podría mostrar los siguientes mensajes cada vez que se intente un acceso a la base de datos.2. que es dónde la herramienta de despliegue puso el fichero HTML. Bonus. tecleamos los nombres JNDI nosotros mismos. • Marcar la caja Return Client Jar. Se mostrará una caja de diálogo Deploy BonusApp. • Cerramos la ventana del verificador porque ahora estamos listos para desplegar la aplicación. Nota: En la versión 1.war al fichero WAR durante su creacción. Esto significa que la herramienta DeployTool no puso la extensión . Al marcar esta caja se crea un ficher JAR con la información de despliegue necesaria por el bean de entidad.jsp procesa nuestros datos y devuelve una página HTML con el bono calculado. • • Pulsamos Next .1 del software podríamos obtener un error tests app. y pulsamos la tecla Return.www. Nos aseguramos de que los nombres JNDI muestran calcs para CalcBean. Nos aseguramos de que el nombre Context Root muestra JSPRoot. bonus para BonusBean y jdbc/Cloudscape para BonusDB.WebURI. Fax: 6322529 .

www.ciisa.0"?> <report> <bonusCalc ssnum="777777777" bonusAmt="300.Santiago Chile 90 .0" /> </report> Huérfanos 835 piso 20 oficina 2003.cl . Fax: 6322529 . 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 versión más 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.Estos mensajes significan que no se suministraron nombres de usuarios ni passwords para acceder a la base de datos. Fonos: * 6322497.*6322102. Podemos ignorar estos mensajes porque los nombres de usuario y las passwords no son necesarios para acceder a la base de datos Cloudscape.