Está en la página 1de 216

Módulo 4

Desarrollando
aplicaciones para la
plataforma Java

Profesional en
Plataforma

JAVA
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Contenido
Introducción y Objetivos ........................................................................................................ 1
Unidad 1. Ubicando el modelo Java EE en contexto .................................................................... 2
Diferentes versiones y plataformas Java existentes ............................................................................................... 3
Entornos gráficos IDE’s ........................................................................................................................................... 5
Descripción de aplicaciones empresariales JEE ...................................................................................................... 6
Introducción a las APIs y servicios Java EE .............................................................................................................. 7
Introducción a los Servidores de Aplicaciones........................................................................................................ 7
Unidad 2. Modelo de componentes Java EE y pasos de desarrollo ................................................ 9
Patrones de diseño ................................................................................................................................................. 9
Modelo Vista Controlador .................................................................................................................................... 11
Comunicación Síncrona y Asíncrona ..................................................................................................................... 14
Capas de arquitectura JEE .................................................................................................................................... 16
Empaquetado de aplicaciones JEE ........................................................................................................................ 17
Unidad 3. Modelo de componentes Web ................................................................................. 19
Componentes web en una aplicación Java EE ...................................................................................................... 19
Envío de información request y response HTTP ................................................................................................... 21
Diferenciación entre información con servlets y JSP ............................................................................................ 24
Unidad 4. Desarrollando Servlets ........................................................................................... 27
CGI ........................................................................................................................................................................ 27
Ciclo de vida de un servlet .................................................................................................................................... 28
Estructura de un servlet ....................................................................................................................................... 29
Configuración de los Servlets mediante anotaciones y descriptores.................................................................... 31
Uso de las APIs request y response en servlets ................................................................................................... 32

Métodos de información del servidor con servlets............................................................................. 39


Unidad 5. Desarrollando con la tecnología de páginas JSP........................................................ 57
Características de Java Server Pages .................................................................................................................... 58
Elementos dentro de Java Server Pages ............................................................................................................... 59
Variables implícitas en las páginas JSP ................................................................................................................. 63
Action Tags ........................................................................................................................................................... 65
Unidad 6. Modelo de componentes EJB................................................................................... 90
Componentes EJB ................................................................................................................................................. 90

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Tipos de beans...................................................................................................................................................... 92
Anotaciones de un bean ....................................................................................................................................... 93
Role de EJB dentro de las aplicaciones JEE ........................................................................................................... 94
Estructura de EJB .................................................................................................................................................. 95
Unidad 7. Implementación de las sesiones EJB 3.0 ................................................................. 101
Tipos de Beans Session ....................................................................................................................................... 101
Ciclo de vida de los beans de Session ................................................................................................................. 102
Clientes del Bean ................................................................................................................................................ 104
Unidad 8. La persistencia API de Java ................................................................................... 120
Beans de Entidad ................................................................................................................................................ 120
Anotaciones de entidades POJO’s ...................................................................................................................... 121
Búsquedas de datos en Entidades ...................................................................................................................... 127
Unidad 9. Implementando una política transaccional ............................................................... 146
Conceptos clave de transacciones ...................................................................................................................... 146
Especificaciones transacción JEE ........................................................................................................................ 148
Transacciones JTA............................................................................................................................................... 151
Unidad 10. Desarrollando Aplicaciones Java usando mensajería............................................... 154
Servicios de mensajería ...................................................................................................................................... 154
Java Message Service API ................................................................................................................................... 155
Modelo de programación de JMS ....................................................................................................................... 156
Message Driven Bean ......................................................................................................................................... 159
Unidad 11. Desarrollo del envío de mensajes ......................................................................... 170
Interceptores ...................................................................................................................................................... 170
Implementación de los mensajes en Beans MDB ............................................................................................... 173
Contenedor de JMS ............................................................................................................................................ 174
Unidad 12. Modelo de los servicios Web ................................................................................ 185
Estructura de los servicios Web .......................................................................................................................... 185
Modelo de Servicios Web ................................................................................................................................... 187
Servicios JAX-RS .................................................................................................................................................. 188
Unidad 13. Implementación de Servicios Java EE Web Services con JAX-WS .............................. 191
Servicios JAX-WS ................................................................................................................................................ 191
Unidad 14. Implementación de una política de seguridad......................................................... 204
Implementación de la seguridad servidor y EJB ................................................................................................. 204

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Mapeo de Roles a grupos ................................................................................................................................... 207
Seguridad de aplicaciones web en servlets y jsp ................................................................................................ 210

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Introducción y Objetivos

Introducción
J2EE ( Java2 Entreprise Edition ) ofrece un conjunto de especificaciones y técnicas que proporcionan
soluciones completas, seguras, estables y escalables para el desarrollo, despliegue y gestión de
aplicaciones en múltiples niveles de funcionalidad basadas en servidores. J2EE reduce el coste y la
complejidad de desarrollo, lo cual redunda en rapidez de desarrollo.
La plataforma J2EE define un estándar para el desarrollo de aplicaciones de múltiples niveles
(servidores Web, de aplicaciones, de base de datos, etc.).
Gracias a que su funcionamiento se basa en componentes modulares que incluyen un conjunto de
servicios predefinidos, se simplifica la tarea de la producción de sistemas. J2EE extiende las ventajas
de la plataforma Java 2 (como por ejemplo, seguridad, la portabilidad de programas, el acceso a las
bases de datos, etc.) con la integración de recursos como Enterprise JavaBeans, Servlets Java,
JavaServer Pages, y la tecnología XML.
A continuación encontrará toda la información relacionada con la plataforma J2EE.

Objetivos
Los participantes que realicen este módulo:
 Conocerán que es la plataforma J2EE y para que sirve o no sirve.
 Aprenderán a usar los elementos que la conforman.
 Conocerán y utilizarán los diferentes recursos de la plataforma J2EE.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 1. Ubicando el modelo Java EE en
contexto
Introducción
J2EE no es un producto es una especificación, en base a esta especificación existen muchas
implementaciones.
Las implementaciones son proporcionadas por fabricantes a terceros (IBM, BEA...), estas
implementaciones deben de cumplir la especificación J2EE.
Elementos de la especificación Java EE
 Java EE Platform: estándar representado por un conjunto de APIs y directivas, soportadas
por un servidor de aplicación.
 Java EE Server: implementación de referencia de un servidor de aplicaciones para Java EE
 Java EE Testsuite: Java EE Compatibility Testsuite (CTS), certificación de implementaciones
de Java EE etc.
 Java EE Blueprints: consejos para el desarrollo de aplicaciones Java EE, patrones de diseño y
un ejemplo de aplicación.
Existen multitud de entornos de desarrollo para Java, cada compañía con cierto peso en la
tecnología Java dispone del suyo propio, JDeveloper (Oracle), NetBeans (Sun), Eclipse (IBM), etc.
Para simplificar el desarrollo web y clarificar las responsabilidades de cada uno de los componentes
de un proyecto, las aplicaciones web se dividen en capas.
Inicialmente en un entorno sin capas el desarrollo de aplicaciones mezclaba todas las tareas del lado
servidor.
Posteriormente surge el modelo de 3 capas que separa capa cliente, servidor y de datos, y con la
evolución de los servidores de aplicaciones surge la necesidad de crear una cuarta capa, para
separar la lógica de negocio de la transaccional.
Este tipo de arquitectura proporciona mayor control sobre los elementos que entran en juego en el
desarrollo de aplicaciones web.
Dentro de la plataforma Java EE disponemos de varios contenedores. Un contenedor es un entorno
de ejecución específico para un conjunto de objetos de un determinado tipo y con unos fines
concretos.
Por ejemplo, el contenedor Web es un contenedor específico para Servlets y páginas JSP, y que por
tanto provee ciertos servicios útiles para este tipo de objetos, como son la librería JSTL de etiquetas
JSP, o la infraestructura de JSF. En el contenedor de EJB no se proveen estos servicios ya que no
son necesarios para los objetos que albergan.
Las aplicaciones Java EE están establecidas para Internet. Toda aplicación JEE debe tener un
servidor de aplicaciones en el que se incluyan los diversos elementos que tengamos ubicados en
nuestro proyecto.
Dentro de las aplicaciones JEE existen tres niveles:
 Maquina Cliente: Es lo que el cliente visualizará al acceder a nuestra aplicación.
 Servidor J2EE: Es el servidor de aplicaciones que contendrá en su interior toda la lógica que
hayamos incluido en el proyecto, elementos tales como páginas JSP, servlets o Enterprise
JavaBeans.
 Servidor BBDD. Es el sistema que ofrecerá información a nuestro proyecto y que podremos
representar en el cliente mediante los elementos incluidos en el servidor de aplicaciones.
En este gráfico podemos visualizar los niveles de arquitectura y alojamiento de cualquier sitio web
Java EE:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Objetivo
Visualizar los componentes más importantes de la arquitectura Java EE, anteriormente conocida
como J2EE, y los servicios que provee y podemos emplear en las diferentes aplicaciones web.

Diferentes versiones y plataformas Java existentes


Existen varias Ediciones de Java, cada una de ellas diseñada para cierto entorno en particular.
Las ediciones de Java más importantes son:
* Java Standard Edition (Java SE)
* Java Micro Edition (Java ME)
* Java Entreprise Edition (Java EE)
* Java Card
Java Standard Edition es la edición que se emplea en computadoras personales (desktops y
laptops). Se le conoce también como Java Desktop (escritorio) y es la versión que necesitamos
instalar para poder programar en Java en el ordenador.
A pesar de que su utilidad sirva para crear aplicaciones de escritorio, su enfoque está destinado a
comprender el lenguaje Java y los conceptos básicos del lenguaje.
J2SE es una colección de APIs del lenguaje de programación Java útiles para muchos programas de
la Plataforma Java.
La Plataforma Java Enterprise Edition incluye todas las clases en el entorno Java SE, además de
librerías que son utilizados en cualquier desarrollo Java, independientemente del tipo de desarrollo.
Java Micro Edition es la edición de Java que se emplea en dispositivos móviles, tales como los
teléfonos móviles.
Es una versión reducida de Java SE standard con ciertas extensiones enfocadas a las necesidades
particulares de este tipo de dispositivos.
La plataforma Java Micro Edition, o Java ME (anteriormente J2ME), es una colección de APIs en Java
orientadas a productos de consumo móviles, tales como PDAs, teléfonos móviles o
electrodomésticos.
Java ME se ha convertido en una gran opción en el momento de crear un desarrollo para dispositivos
móviles, como pueden ser juegos en PDAs.
Ofrece un entorno de desarrollo en el que podemos emular en un PC todo el entorno gráfico durante
la fase debug del proyecto y, posteriormente, implementar el proyecto ya creado en el dispositivo
móvil.
Al utilizar tecnologías Java en el desarrollo de aplicaciones o juegos con estas APIs, resulta bastante
sencillo de migrar las aplicaciones a otros dispositivos, debido a que J2ME es una “mini” edición de
Java Enterprise Edition.
J2EE es un grupo de especificaciones diseñadas por Sun que permiten la creación de aplicaciones
empresariales enfocadas al entorno web.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
J2EE es solamente una especificación sobre un conjunto de “reglas” que deben seguir las páginas
web de servidor para crear aplicaciones empresariales. Algunos productos siguen todas las
especificaciones, pero no todos cumplen es estándar completo.
Java Card es la versión de Java enfocada a aplicaciones que se ejecutan en tarjetas de crédito con
chip.
Es una versión muy recortada de Java. Un Java Card es una tarjeta capaz de ejecutar mini-
aplicaciones Java. En este tipo de tarjetas el sistema operativo es una pequeña máquina virtual
Java (JVM) y en ellas se pueden cargar dinámicamente aplicaciones desarrolladas específicamente
para este entorno.
Existen diferentes versiones de Java que han ido apareciendo a lo largo del tiempo y dónde el
entorno de desarrollo ha ido evolucionando, incluyendo mejoras en cada uno de las plataformas
existentes.
Las versiones de Java existentes son las siguientes:
Java 1
Java 1.0 (1996): 8 paquetes, 212 clases – Es la primera versión pública.

La presión hizo que se hiciera pública demasiado pronto, lo cual significa que el diseño del lenguaje
no es demasiado pronto y aparecieron multitud de errores en su entorno de clases. Dicha versión
creaba un código poco fiable debido a que apareció demasiado temprano y no solucionaron
problemas del lenguaje.
Java 1.1 (1997): 23 paquetes, 504 clases - Mejoras de rendimiento en JVM, es decir, máquina
virtual de Java, nuevo modelo de eventos en AWT, clases anidadas, serialización de objetos, API de
JavaBeans, archivos jar, internacionalización, API Reflection (Reflexión), JDBC (Java Data base
Connectivity), RMI (Remote Method Invocation).

Se implementó la firma del código y la autentificación. Fue la primera versión lo suficientemente


estable y robusta.
Java 2
Java 1.2 (1998): 59 paquetes, 1520 clases - JFC (Swing), Drag and Drop,, Java2D, Corba, API
Collections.

Se produjeron notables mejoras en todos los niveles. Para darle más importancia a las mejoras, Sun
lo renombró como "Java 2".
El JDK (Java Development Kit) se renombra al término SDK (Software Development Kit).
Se divide en J2SE, J2EE y J2ME.
Java 1.3 (2000) - 77 paquetes, 1595 clases: Orientada sobre todo a la resolución de errores y a la
mejora del rendimiento. Se producen algunos cambios menores como la inclusión de JNDI (Java
Naming and Directory Interface) y la API Java Sound.

También incluye un nuevo compilador de alto rendimiento JIT (Just In Time).


Java 1.4 (2002) - 103 paquetes, 2175 clases: También conocido como Merlin. Mejora notablemente
el rendimiento y añade entre otros soporte de expresiones regulares, una nueva API de
entrada/salida de bajo nivel (NIO, New I/O), clases para el trabajo con Collections, procesado de
XML; y mejoras de seguridad como el soporte para la criptografía mediante las Java Cryptography
Extension (JCE), la inclusión de la Java Secure Socket Extension (JSSE) y el Java Authentication and
Authorization Service (JAAS).

Java 1.5 (2004) - 131 paquetes, 2656 clases: También conocido como Tiger, renombrado por
motivos de marketing como Java 5.0.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Incluye como principales novedades: tipos genéricos (generics), autoboxing/unboxing conversiones
implícitas entre tipos primitivos y los wrappers correspondientes, Enumerados, Bucles simplificados,
printf, funciones con número de parámetros variable, Metadatos en clases y métodos.
Java SE 6 (2006): También conocido como Mustang.

Sun cambió el nombre "J2SE" por Java SE y eliminó el ".0" del número de versión.
Los cambios más importantes introducidos en esta versión son: Incluye un nuevo marco de trabajo
y APIs que hacen posible la combinación de Java con lenguajes dinámicos como PHP, Python, Ruby y
JavaScript. Incluye el motor Rhino, de Mozilla, una implementación de Javascript en Java. Incluye
un cliente completo de Servicios Web y soporta las últimas especificaciones para Servicios Web,
como JAX-WS, JAXB, STAX y JAXP. Mejoras en la interfaz gráfica y en el rendimiento.
Java SE 7 – Nombre en clave Dolphin: Todavía está en fase producción. Se estima su lanzamiento
para finales de 2010 o principios de 2011. Las mejoras que se están avanzando dentro de esta
nueva versión son:

Soporte para XML dentro del propio lenguaje.


Un nuevo concepto de superpaquete.
Soporte para closures.
Introducción de anotaciones estándar para detectar fallos en el software.
Además de los cambios en el lenguaje Java, con el paso de los años se han efectuado muchos más
cambios drásticos en la biblioteca de clases de Java (Java class library) que ha crecido de unos
pocos cientos de clases en su primera versión JDK 1.0 hasta más de tres mil incluidas en la
actualidad.
APIs completamente nuevas, como Swing y Java2D, han sido introducidas y muchos de los métodos
y clases originales de JDK 1.0 han quedado obsoletos para el lenguaje y ya no se utilizan en los
desarrollos.

Entornos gráficos IDE’s


Un JDK|SDK ofrece las herramientas para compilar y ejecutar programas en Java. Podemos
compilar las clases sin necesidad de tener un entorno gráfico sobre el que desarrollar, pero dicha
tarea sería muy costosa dependiendo del tipo de proyecto, ya que existen multitud de
configuraciones posibles dependiendo del tipo de aplicación empresarial que estemos desarrollando.
Un IDE o entorno de trabajo de Java, ofrece un ambiente de trabajo para proyectos complejos, es
decir, si compilamos una o dos clases en un paquete o individualmente, es posible que el comando
javac ofrecido en los JDK/SDK sea suficiente, pero si nuestros proyecto está compuesto por 100 o
200 clases, javac sería muy lento y costoso.
Los IDE's (Integrated Development Environment) ofrecen un entorno gráfico en el que se tiene
acceso a mayor número de herramientas no ofrecidas en los SDK's.
Ofrece complidarores más elaborados, check-points dentro de la compilación, creación de WAR's
(Web-Archives), "Wizards" para acelerar desarrollo, entre otras cosas.
Los entornos de desarrollo más utilizados hoy en día son:
 NetBeans (http://www.netbeans.org) Open-Source.
 Eclipse (http://www.eclipse.org) Open-Source
 Sun Java Studio (http://developers.sun.com/jsenterprise/index.jsp) de Sun
 JBuilder (http://www.codegear.com/products/jbuilder) de Borland
 WebSphere Studio (http://www306.ibm.com/software/awdtools/developer/application/) de
IBM
 JDeveloper (http://www.oracle.com/technology/products/jdev/index.html) de Oracle

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Descripción de aplicaciones empresariales JEE
Las aplicaciones empresariales con la tecnología Java JEE, se ejecutan en un servidor de
aplicaciones.
Una aplicación empresarial Java EE está formada por un conjunto de módulos donde cada módulo es
un conjunto de uno o más componentes que se ejecutan en el mismo contenedor.
Un componente no es más que un elemento de software, podría ser un componente web como una
página JSP o un Servet, un componente EJB, etc.
Estos componentes se ejecutan dentro de su correspondiente contenedor dentro del servidor de
aplicaciones.
El contenedor no es más que un entorno de ejecución que gestiona los componentes, por eso, los
componentes deben de cumplir un contrato que establece el contenedor.
Ese contrato no es más que un conjunto de métodos que se deben implementar en el componente y
que permite al contenedor interactuar con él.
Existen dos tipos de contenedores dentro de un servidor de aplicaciones:
 Contenedor WEB: Almacenan componentes de presentación. Es el encargado de gestionar
los componentes servlets y páginas JSP.
 Contenedor EJBs: Administran la ejecución de EJBs. Es el encargado de gestionar los
componentes EJBs.
Los contenedores ofrecen servicios a las aplicaciones y se accede a los servicios JEE a través de las
API’s.

El contenedor es el encargado de gestionar el ciclo de vida de los componentes, realizar la reserva


de recursos, etc.
Algunos de estos servicios son servicios declarativos, es decir, que algunos servicios se declaran en
lugar de programarse.
La declaración se realiza mediante descriptores de despliegue. Cada módulo dispone de un
descriptor de despliegue. El descriptor de despliegue es fichero XML que realiza una descripción de
como se deben desplegar esos componentes en el contenedor del servidor de aplicaciones.
Los módulos que forman una aplicación empresarial pueden ser de tres tipos:
 Archivos JAR (Java Archive): Los archivos JAR permiten agrupar distintos archivos .java en
uno solo. Es el empleado para empaquetar componentes EJBs.
 Archivos WAR (Web Application Archive): Los archivos WAR permiten empaquetar en una
sola unidad aplicaciones web completas (servlets, páginas JSPs, contenido estático como
imágenes y otros recursos Web).
 Archivos EAR (Enterprise Application Archive): Los archivos EAR son archivos desplegables en
servidores de aplicaciones JEE. Contienen archivos WAR y EJBs empaquetados en ficheros
JAR.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Por lo que podemos decir que existen tres tipos de aplicaciones Java EE:
 Aplicaciones Web JAVA.
 Objetos distribuidos EJBs.
 Aplicaciones empresariales que engloban a las dos anteriores, aplicaciones web JAVA y
objetos distribuidos EJBs.

Introducción a las APIs y servicios Java EE


Las clases en las APIs de Java se organizan en grupos distintos llamados paquetes.
Cada paquete contiene un conjunto de interfaces, clases y excepciones relacionadas con el entorno
de trabajo.
La información sobre los paquetes que ofrece cada plataforma puede encontrarse en la
documentación de dicha plataforma de desarrollo.
El conjunto de las APIs es controlado por Sun Microsystems junto con otras entidades a través del
programa JCP (Java Community Process). Las compañías del JCP pueden influir de forma activa en
el diseño y desarrollo de las APIs.
Vamos a visualizar algunos de los servicios que provee Java EE y que podemos emplear en cualquier
servidor de aplicaciones que siga este estándar.
 Java Transaction API (JTA): Consta de dos partes y define las interfaces entre el manejador
de transacciones y las partes involucradas en un sistema de transacciones distribuido, el
manejador de recursos, el servidor de aplicaciones y las aplicaciones transaccionales.
 Java Persistente API (JPA): Para dotar de persistencia a objetos del lenguaje.
 Java Message Service (JMS): Sistema de mensajería, permite mensajes punto a punto y
sistemas publicado suscrito.
 Java Naming Direct Interface (JNDI): Sistema de nombrado para localizar recursos o
componentes de proveedores.
 JavaMail: Para manejo de correo electrónico.
 Java Beans Active Framework (JAF): Manejo de datos en diferentes tipos mime, ligado al uso
del correo.
 Java API for XML Processing (JAXP): Soporte para el manejo de XML.
 Java EE Connector Arquitectura: Permite el acceso a otro tipo de sistemas de información
empresarial por medio del desarrollo de un pluggin, similar a los conectores JDBC.
 Java Autentícation and Authorization Service (JAAS): Provee servicios de seguridad de
autenticación y autorización.
 Servicios Web (JAX-WS): Para manejo de servicios web.

Introducción a los Servidores de Aplicaciones


Como consecuencia del éxito del lenguaje de programación Java, el término servidor de aplicaciones
hace referencia a un servidor de aplicaciones Java EE.
WebSphere (IBM) y WebLogic (Oracle, antes BEA Systems) están entre los servidores de aplicación
Java EE privados más conocidos. EAServer (Sybase Inc.) es también conocido por ofrecer soporte a
otros lenguajes diferentes a Java, como PowerBuilder.
El servidor de aplicaciones JOnAS, desarrollado por la empresa ObjectWeb, fue el primer servidor de
aplicaciones libre en lograr certificación oficial de compatibilidad con J2EE.
JBoss es otro servidor de aplicaciones libre y muy popular en la actualidad, así como GlassFish de
SUN que viene integrado con NetBeans.
Mucha gente confunde Tomcat como un servidor de aplicaciones; sin embargo, es solamente un
contenedor de servlets.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Java EE provee estándares que permiten a un servidor de aplicaciones servir como "contenedor" de
los componentes que conforman dichas aplicaciones.
Estos componentes, escritos en lenguaje Java, generalmente se conocen como Servlets, Java Server
Pages (JSPs) y Enterprise JavaBeans (EJBs) y permiten implementar diferentes capas de la
aplicación, como la interfaz de usuario, la lógica de negocio, la gestión de sesiones de usuario o el
acceso a bases de datos remotas.
La portabilidad de Java también ha permitido que los servidores de aplicación Java EE se encuentren
disponibles sobre una gran variedad de plataformas, como Unix, Microsoft Windows y GNU/Linux.
Existen multitud de servidores de aplicaciones de Java EE. Dichos servidores deben estar
certificados por la plataforma Sun para poder albergar aplicaciones JEE.
Muchos servidores de aplicaciones vienen integrados dentro de un IDE específico, es decir, dentro de
un entorno de desarrollo para JEE.
Algunos servidores certificados de JEE son los siguientes:
 JOnAS: servidor de aplicaciones de código abierto de ObjectWeb
 JBoss: desarrollado inicialmente por JBoss Inc y adquirido posteriormente por Red Hat.
Existe una versión de código abierto soportada por la comunidad y otra empresarial.
 Sun Java System Application Server Platform Edition 9.0: Es un servidor basado en
GlassFish.
 Oracle WebLogic Application Server 10.0: antes conocido como BEA Systems.
 Servidor de Aplicaciones SAP NetWeaver, Java EE 5 Edition de SAP
 JEUS 6, un Servidor de aplicaciones específico de Linux de TmaxSoft
 Apache Gerónimo 2.0
 IBM WebSphere Application Server Community Edition 2.0: basado en el servidor Apache
Gerónimo
 Oracle Containers for Java EE 11
 GlassFish: un servidor de aplicaciones de código abierto de Sun
 Apache OpenEJB vía Apache Gerónimo

Ver Video: Servidores y aplicaciones disponibles con NetBeans,


en la Unidad 1, en el Módulo 4, en la plataforma elearning

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 2. Modelo de componentes Java EE y
pasos de desarrollo
Introducción
Java es un lenguaje de programación muy completo, el cual es utilizado para la creación de
aplicaciones de todo tipo, desde aplicaciones para dispositivos móviles como aplicaciones
empresariales de tipo web, aplicaciones de escritorio y aplicaciones de automatización de procesos.
Java como lenguaje es muy potente y versátil y ha sido adoptado en todas las industrias como:
 Financiera: Sistemas de automatización para aplicaciones de procesamiento de ordenes de
compra e intercambio de valores en el mercado.
Estas aplicaciones son aplicaciones que requieren el procesamiento de un gran número de
transacciones por segundo.
En esta industria también se generan aplicaciones de servicio al cliente para acceso a servicios
bancarios y financieros
 Defensa: El departamento de defensa de los Estados Unidos por ejemplo usa sistemas
desarrollados en Java como controladores de diferentes dispositivos en tiempo real.
 Educación, Ingeniería, Biogenética, Información Geográfica, eCommerce,Logistica, ERP, etc
Respecto a que herramientas y patrones de desarrollo debemos utilizar, todo depende del tipo de
proyecto que vayamos a implementar.
En el mundo de Java para programar, no necesitamos más que un editor de texto y el compilador de
Java javac.
Pero para ser más rápidos y eficaces en las tareas, es recomendable utilizar un IDE como Eclipse,
NetBeans, IntelliJ, etc.
Eclipse y NetBeans son gratis y tienen una gran cantidad de componentes adicionales que facilitan el
desarrollo de todo tipo de aplicaciones.
Con respecto a arquitectura, todo depende del tipo de aplicación y requerimientos.
Dada la flexibilidad de Java podemos crear aplicaciones desktop usando SWING o la plataforma de
Eclipse.
Para Web podemos usar un servidor de aplicaciones open source o comercial y desarrollar un
proyecto web application usando JSP, Servlets, y una serie de frameworks como Spring.
Objetivo
 Conocer los diferentes tipos de aplicaciones distribuidas dentro de la plataforma Java EE.
 Conocer diferentes patrones de diseño entre lo que destacan las llamadas asíncronas y el
modelo vista controlador.

Patrones de diseño
Un patrón de diseño es una abstracción de una solución en un nivel alto. Los patrones solucionan
problemas que existen en muchos niveles de abstracción. Hay patrones que abarcan las distintas
etapas del desarrollo, desde el análisis hasta el diseño y desde la arquitectura hasta la
implementación.
Algunas personas definen un patrón como una solución recurrente para un problema en un contexto.
Un contexto es el entorno, situación, o condiciones relacionadas dentro de las cuales existe algo.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Un problema es una cuestión inacabada, algo que se necesita investigar y resolver. Un problema se
puede especificar mediante un conjunto de causas y efectos. Usualmente un problema está
restringido al contexto en el que ocurre.
La solución se refiere a la respuesta al problema dentro de un contexto que ayuda a resolver las
dificultades.
Entonces, si tenemos una solución a un problema en un contexto, ¿es un patrón? No
necesariamente. También necesitamos asociar la característica de recurrencia con la definición de un
patrón.
Los patrones deberían comunicar soluciones de diseño a los desarrolladores y arquitectos que los
leen y los utilizan. Aunque el concepto de patrón es bastante simple, definir realmente el término es
muy complejo.
Hemos señalado sólo las referencias para que puedas indagar en más profundidad en la historia de
los patrones y aprender sobre ellos en otras áreas. Sin embargo, deberías tener en mente que la
definición de patrón que hemos adoptado funciona. En nuestro catálogo, se describe un patrón de
acuerdo a sus principales características: contexto, problema y solución, junto con otros aspectos
importantes, como causas y consecuencias. La página que describe la plantilla de patrones explica
estas características en más detalle.
A cada diseño de proyecto le sigue el problema que trata de resolver, la solución que aporta y las
posibles desventajas asociadas.
Un desarrollador debe buscar un equilibrio entre las ventajas y las desventajas a la hora de decidir
que patrón utilizar. Lo normal es, como observará a menudo en la tecnología de programación y
otros campos, es buscar la media entre flexibilidad y rendimiento.
La mayoría de las personas utiliza patrones de diseño cuando perciben un problema en su proyecto,
como por ejemplo, el rendimiento.
Un patrón de diseño es el trabajo de una persona que ya se encontró con el problema
anteriormente, intentó muchas soluciones posibles, y escogió y describió una de las mejores.
Todos los proyectos grandes utilizan los patrones de diseño para solucionar los problemas e
implementar el rendimiento de la aplicación.
Los patrones de diseño se pueden dividir en tres grandes categorías basadas en su propósito:
creacionales, estructurales y de comportamiento.
Creacionales: Los patrones creacionales tratan con las formas de crear instancias de objetos. El
objetivo de estos patrones es abstraer el proceso de instanciación y ocultar los detalles de cómo los
objetos son creados o inicializados.

Estructurales: Los patrones estructurales describen como las clases y objetos pueden ser
combinados para formar grandes estructuras y proporcionar nuevas funcionalidades. Estos objetos
insertados pueden ser incluso objetos simples u objetos compuestos.

Comportamiento: Los patrones de comportamiento ayudan a definir la comunicación y relación entre


los objetos de un sistema. El propósito de este patrón es reducir el acoplamiento entre los objetos.

Podemos subdividir a su vez los patrones en Clases y Objetos:


Creacionales
Creacional de la Clase
Los patrones creacionales de Clases usan la herencia como un mecanismo para lograr la
instanciación de la Clase.
Creacional del objeto
Los patrones creacionales de objetos son más escalables y dinámicos comparados de los patrones
creacionales de Clases.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Estructurales
Estructural de la Clase
Los patrones estructurales de Clases usan la herencia para proporcionar interfaces más útiles
combinando la funcionalidad de múltiples Clases.
Estructural de Objetos
Los patrones estructurales de objetos crean objetos complejos agregando objetos individuales para
construir grandes estructuras. La composición del patrón estructural del objeto puede ser cambiado
en tiempo de ejecución, el cual nos da flexibilidad adicional sobre los patrones estructurales de
Clases
Comportamiento
Comportamiento de Clase
Los patrones de comportamiento de Clases usan la herencia para distribuir el comportamiento entre
Clases.
Comportamiento de Objeto
Los patrones de comportamiento de objetos nos permiten analizar los patrones de comunicación
entre objetos relacionales, como objetos incluidos en un objeto complejo.
Con la aparición del entorno J2EE, aparecieron nuevos catálogos de patrones de diseño. J2EE es
una arquitectura por si misma que integra otras arquitecturas, incluyendo servlets, JavaServer
Pages, Enterprise JavaBeans, y más. Existen 5 capas en la arquitectura J2EE:
 Cliente
 Presentación
 Negocios
 Integración
 Recurso

Los patrones J2EE se pueden dividir en tres categorías:


 Capa de presentación
 Capa de Negocios
 Capa de Integración

Modelo Vista Controlador


El modelo actual de páginas web, define que las peticiones de los clientes son solicitudes a páginas
de servidor (jsp, servlets…) que contienen la lógica de negocio y el diseño HTML en un mismo ligar.
Las páginas ejecutan acciones del usuario que ha realizado sobre esa página. Dichas acciones son
capturadas por clases o pueden estar escritas en una clase Servet.
En este tipo de arquitectura conocida, el cliente hace Request a objetos de la capa de presentación
(Pagina del servidor), que luego llama a su código controlador para pedirle funcionalidad.
En el caso de un diseño de datos MVC, el Request se realiza a un objeto de tipo Controlador que
crea una presentación como Response a esa solicitud.
En los frameworks MVC, las URLs se mapean directamente a clases, estas son denominadas
"Controladoras" y son las que procesan los Request entrantes, manejando las entradas del usuario,
sus interacciones y ejecutando la lógica apropiada para el proceso.
Una clase controladora llama a una vista, la cual genera la salida HTML que se enviará como
Response.
Dicho modelo MVC permite diseñar en tres capas de negocio y no poner todo el código en las
interfaces de usuario de tu sistema (IU).
La idea consiste en tener 3 niveles de funcionalidad bien definidos:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Capa de presentación: Con nuestras Interfaces (páginas HTML.) y sus controles visuales
(controles de formulario) junto con sus eventos.

Capa de negocio: Lógica del dominio. Aquí irá todo el código que define las reglas de negocio
(cálculos, validaciones). Surge de los procesos que hemos encontrado en el análisis.

Capa de acceso a datos: El código que permite acceder a las fuentes de datos. Esencialmente
trata sobre 4 operaciones básicas, llamadas CRUD (por Create-Retrieve-Update y Delete), que se
realizan sobre cualquier fuente de datos (normalmente alguna base de datos relacional).

El modelo de arquitectura Model-View-Controller (MVC) separa una aplicación en tres componentes


principales: el modelo, la vista y el controlador.
El marco de J2EE proporciona una alternativa al modelo de páginas de servidor para crear
aplicaciones web.
El marco de J2EE es un marco de presentación de poca complejidad y fácil de comprobar que se
integra con las características de Java existentes, como el acceso a datos o la representación de
datos en las páginas.
MVC es un modelo de diseño estándar con el que están familiarizados muchos desarrolladores.
Algunos tipos de aplicaciones web salen beneficiadas con el marco de MVC.
Otras seguirán utilizando el modelo de la aplicación J2EE tradicional que está basado en formularios
HTML, código del servidor y postbacks. Otros tipos de aplicaciones web combinarán las dos
estrategias; una no excluye a la otra.
El marco de MVC incluye los componentes siguientes:
Modelos. Los objetos de modelo son las partes de la aplicación que implementan la lógica del
dominio de datos de la aplicación.
A menudo, los objetos de modelo recuperan y almacenan el estado del modelo en una base de
datos. Por ejemplo, un objeto Product podría recuperar información de una base de datos, trabajar
con ella y, a continuación, escribir la información actualizada en una tabla Productos de una base de
datos.
En las aplicaciones pequeñas, el modelo es a menudo una separación conceptual en lugar de física.
Por ejemplo, si la aplicación solo lee un conjunto de datos y lo envía a la vista, la aplicación no tiene
un nivel de modelo físico y las clases asociadas. En ese caso, el conjunto de datos asume el rol de
un objeto de modelo.
Vistas. Las vistas son los componentes que muestra la interfaz de usuario de la aplicación.
Normalmente, esta interfaz de usuario se crea a partir de los datos de modelo. Un ejemplo sería
una vista de edición de una tabla Productos que muestra cuadros de texto, listas desplegables y
casillas basándose en el estado actual de un objeto Product.
Controladores. Los controladores son los componentes que controlan la interacción del usuario,
trabajan con el modelo y por último seleccionan una vista para representar la interfaz de usuario.
En una aplicación MVC, la vista solo muestra información; el controlador administra y responde a los
datos proporcionados por el usuario y su interacción. Por ejemplo, el controlador administra los
valores de la cadena de consulta y pasa estos valores al modelo, que a su vez podría utilizarlos para
consultar la base de datos.
El modelo de MVC ayuda a crear aplicaciones que separan los aspectos diferentes de la aplicación
(lógica de entrada, lógica comercial y lógica de la interfaz de usuario), proporcionando un
acoplamiento entre estos elementos.
El modelo especifica dónde se debería encontrar cada tipo de lógica en la aplicación. La lógica de la
interfaz de usuario pertenece a la vista. La lógica de entrada pertenece al controlador. La lógica
comercial pertenece al modelo.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Esta separación ayuda a administrar la complejidad al compilar una aplicación, ya que permite
centrarse en cada momento en un único aspecto de la implementación. Por ejemplo, podemos
centrarnos en la vista sin estar condicionado por la lógica comercial.
El acoplamiento entre los tres componentes principales de una aplicación MVC favorece el desarrollo
paralelo. Por ejemplo, un desarrollador de software puede trabajar en la vista, un segundo
desarrollador puede ocuparse de la lógica del controlador y un tercero se puede centrar en la lógica
comercial del modelo.
En este gráfico podemos visualizar cómo son las características de envío de una página web con la
lógica tradicional de J2EE utilizando páginas de servidor.

El ciclo de vida de una aplicación MVC es simple. Lo primero de todo es que no realizamos en
ningún momento un postback. No existen métodos de acción para el envío de la página tal y como
los conocemos, sino que cada acción está delimitada por un controlador, que devolverá la Vista final
al usuario.
El usuario realizará una acción en la Vista, que llamará al controlador con una acción delimitada, y el
modelo se encargará de la lógica para poder realizar la acción final.

Si nos fijamos en la lógica MVC, solamente tenemos un manejador, que será el encargado de llamar
a su controlador correspondiente, según la acción del usuario.

Cada página que visualiza el usuario es independiente a la lógica de negocio, y cada una es
representada individualmente al realizar acciones sobre ella.
Con la lógica MVC, lo que hacemos es representar al usuario acciones para realizar las llamadas.
Vamos a ver un ejemplo, tenemos acciones para Details y Orders.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Cuando el usuario hace una petición sobre una de esas acciones, el manejador se encarga de enviar
dicha información al servidor, y dependiendo de la acción que envía el usuario, se llama a un
controlador que representará la vista correspondiente en HTML.
En cambio, si lo hacemos con las páginas JSP, cada página es independiente entre sí y si
quisiéramos cambiar o añadir algo, habría que hacerlo página a página, mientras que con MVC,
habría que hacerlo independiente a cada controlador y vista.

Comunicación Síncrona y Asíncrona


Definición de las comunicaciones:
Síncrona

Quien envía permanece bloqueado esperando a que llegue una respuesta del receptor antes de
realizar cualquier otra tarea.
Asíncrona

Quien envía continúa con su ejecución inmediatamente después de enviar el mensaje al receptor.
Existen dos modos de comunicación entre el cliente (definido como el equipo que requiere servicios
del servidor) y el servidor (máquina desde la que se suministran servicios y que está a la espera de
los requerimientos de los clientes).
Estos dos modos son el síncrono y el asíncrono.
La mayoría de las aplicaciones Web existentes realizan la comunicación de datos con el servidor de
manera síncrona. En una comunicación síncrona, se ejecutan los procesos en el siguiente orden:
1) El cliente realiza una petición al servidor.
2) El servidor envía los datos solicitados y el cliente comienza a recibir los datos.
3) Una vez finalizada la recepción de los datos en la página, el usuario vuelve a tener el control.
Este proceso conduce a que cada vez que se está enviando más información al servidor, el usuario
pierde el control sobre la página Web que está visitando, limitándose de esta manera a esperar que
la aplicación le devuelva el control.
En una aplicación Web que se comunica asíncronamente con el servidor, los procesos son los
siguientes:
1) El cliente realiza una solicitud al servidor.
2) El servidor envía los datos solicitados
3) El cliente comienza a recibir los datos.
El cliente en ningún momento pierde el control de las acciones sobre la página que está
visualizando y permite acciones con el usuario durante la devolución de los datos.
La comunicación asíncrona se puede utilizar para construir interfaces interactivas de usuario que son
muy semejantes a las aplicaciones de escritorio tradicionales.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Las páginas web envían información al servidor para luego devolver una respuesta al cliente con el
código de servidor ya procesado.
Estas llamadas al servidor son muy eficaces, ya que nos permiten tratar elementos de alto nivel
como datos, pero tienen una desventaja, el coste de tiempo desde la llamada al servidor, hasta la
respuesta y el dibujo de la página en el cliente de nuevo.
Existen ciertas acciones en las que no necesitamos realizar llamadas al servidor para poder
realizarlas, como por ejemplo, comprobar si un objeto tiene contenido.
Si pensamos en un caso práctico, sería muy costoso en cuanto a rendimiento enviar una llamada al
servidor para devolver una respuesta de campos de texto vacíos.
Aquí es dónde entran los Scripts del servidor, que son bloques de código JavaScript que se ejecutan
en el cliente y que permiten realizar acciones lógicas sin necesidad de atacar al servidor y esperar
una respuesta.
Dichos scripts de servidor son bloques de código JavaScript que podemos llamar desde controles
creados específicamente para realizar llamadas o podemos llamarlos de forma explicita desde
cualquier control de formulario HTML.
La tecnología más importante dentro de las llamadas asíncronas es AJAX.
AJAX. Acrónimo de Asynchronous JavaScript And XML (JavaScript asíncrono y XML).
Ajax no es una tecnología, es el conjunto de muchas tecnologías (XHTML, CSS, DOM, XML, XSLT,
XMLHttpRequest, JavaScript, JQuery).
Dichas tecnologías se ejecutan en el navegador de los usuarios y mantiene comunicación asíncrona
con el servidor en segundo plano.
De esta forma es posible realizar cambios sobre la misma página sin necesidad de recargarla.
Esto significa aumentar la interactividad, velocidad y la manera de utilizar la misma página con
acciones del usuario sin necesidad de enviar información al servidor.
En aplicaciones AJAX se pueden enviar peticiones al servidor web para obtener solamente la
información necesaria y así ahorrar ancho de banda.
Su desventaja sería que el cargar la página inicial, el proceso es más lento, debido a que primero
tiene que cargar todo el código JavaScript y XML que hará la implementación.
Las acciones de la tecnología Ajax se ejecutan en el cliente, es decir, en el navegador del usuario, y
mantiene comunicación asíncrona con el servidor en segundo plano.
Las tecnologías que forman AJAX son:
 XHTML y CSS, para crear una presentación basada en estándares.
 DOM, para la interacción y manipulación dinámica de la presentación.
 XML, XSLT y JSON, para el intercambio y la manipulación de información.
 XMLHttpRequest, para el intercambio asíncrono de información.
 JavaScript, para unir todas las demás tecnologías.

Estructura de una aplicación Web con tecnología Ajax:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ventajas
 Las páginas no se recargan constantemente.
 El tiempo de espera es menor.
 Se pueden lograr cosas que sin AJAX definitivamente no se podrían hacer.

Desventajas
 Falta de integración con el botón “retroceder” de los navegadores. Esto se debe a que
siempre estamos en la misma página (no la recargamos). Y algunas veces puede llegar a
confundir al usuario.
 Es necesario que el navegador soporte y tenga habilitado JavaScript. No es una gran
desventaja, ya que casi todos los navegadores modernos soportan JavaScript.
 Al tener que ejecutar más código del lado del cliente, puede enlentecerse el rendimiento de la
máquina del cliente. Por eso debe usarse AJAX con moderación.
 Al no recargar las páginas, y siempre estar en la misma, no se tiene una URL a la cual poder
referirse, en caso de querer recomendar la página, o volver a esa página, por eso debe
saberse cuando usar AJAX y cuando no.

Capas de arquitectura JEE


En la arquitectura JEE se contemplan cuatro capas, en función del tipo de servicio y contenedores:
 Capa de cliente: También conocida como capa de presentación o de aplicación. Nos
encontramos con componentes Java (applets o aplicaciones) y componentes que son parte
del diseño web y su lógica en el cliente (HTML, JavaScript, css, etc.).
 Capa Web. Intermediario entre el cliente y otras capas. Sus componentes principales son los
servlets y las páginas JSP. Aunque componentes de capa cliente (applets o aplicaciones)
pueden acceder directamente a la capa EJB, lo normal es que Los servlets/JSPs pueden
llamar a los EJB.
 Capa Enterprise JavaBeans: Permite a múltiples aplicaciones tener acceso de forma
concurrente a datos y lógica de negocio. Los EJB se encuentran en un servidor EJB, que no
es más que un servidor de objetos distribuidos. Un EJB puede conectarse a cualquier capa,
aunque su misión esencial es conectarse con los sistemas de información empresarial (un
gestor de base de datos, ERP, etc.)
 Capa de sistemas de información empresarial.

La visión de la arquitectura es un esquema lógico, no físico. Cuando hablamos de capas nos


referimos sobre todo a servicios diferentes que pueden estar físicamente dentro de la misma
máquina e incluso compartir servidor de aplicaciones y JVM.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Empaquetado de aplicaciones JEE
Una aplicación Java EE es distribuida en un fichero Archivo Empresarial (EAR) que es un Archivo
Java estándar (JAR) con una extensión .ear.
El uso de archivos EAR y módulos hace posible ensamblar una gran cantidad de aplicaciones Java EE
utilizando alguno de los mismos componentes.
No se necesita codificación extra, es solo un tema de empaquetado de varios módulos Java EE en un
fichero EAR.
Un fichero EAR contiene módulos Java EE y descriptores de despliegue. Un descriptor de despliegue
es un documento XML con una extensión .xml que describe la configuración de despliegue de una
aplicación, un módulo o un componente.
Dado que la información en el descriptor de despliegue es declarativa, esta puede ser cambiada sin
la necesidad de modificar el código fuente. En tiempo de ejecución, el servidor Java EE lee el
descriptor de despliegue y actúa sobre la aplicación, módulo o componente como corresponde.
Existen tres tipos de empaquetados dentro de las aplicaciones JEE:
 Archivos JAR (Java Archive)

Características:
- Permiten empaquetar diferentes archivos de java en uno solo.
- Siguen el formato ZIP
- Fueron incorporados en la versión 1.1 del JDK
- Contienen clases Java y recursos que utilizan dichas clases
- Es el empleado para empaquetar componentes EJBs respetando su estructura de directorios.

 Archivos WAR (Web Application Archive)

Características:
- Permiten empaquetar en una sola unidad aplicaciones web java completas
- Pueden empaquetar los siguientes elementos:
o Java Server Pages (JSP)
o Servlets
o Contenido estático como css, HTML o imágenes
o Otros recursos web

 Archivos EAR (Enterprise Application Archive)

Características:
- Archivos desplegables en servidores de aplicaciones J2EE.
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
- Contienen los siguientes elementos:
o Archivos War
o EJBs empaquetados dentro de ficheros jar

Una aplicación JEE se empaqueta en un archivo .ear que no es nada mas que un jar normal y
corriente.
Debe contener obligatoriamente una carpeta META-INF y un fichero application.xml donde estará
toda la meta-información, como su propio nombre indica.
Módulos web: ficheros .war que contienen la capa web
Módulos EJB: que contiene ficheros .jar.
Módulos de adaptadores de recursos
En la práctica, casi todo se reduce a un módulo war y pocos elementos más.
La estructura de un módulo web (empaquetado .war) es la siguiente:
/Raiz
/Raiz/WEB-INF
/Raiz/WEB-INF
/Raiz/WEB-INF/lib
/Raiz/WEB-INF/classes
/Raiz/WEB-INF/tags
El directorio Raíz contiene todos los archivos estáticos (HTML, gráficos, jsp, y los recursos estáticos
de cualquier web)
El directorio WEB-INF debe contener un archivo web.xml que es la información que contendrá la
meta-información de el archivo war.
El directorio WEB-INF/lib contiene las librerías de código .jar
El directorio WEB-INF/classes contendrá las clases compiladas
El directorio WEB-INF/lib contendrá las etiquetas personalizadas

Ver Video: Empaquetado y ejecución de aplicaciones


distribuidas, en la Unidad 2, en el Módulo 4,
en la plataforma elearning

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 3. Modelo de componentes Web

Introducción
La tecnología Java mantiene un glosario completo de las tecnologías estándar de componentes Java.
Existen una serie de componentes que definen una aplicación, dependiendo del tipo de aplicación,
dichos componentes estarán estructurados con una serie de características para conseguir realizar
una aplicación funcional.
Para cada edición de la plataforma Java los componentes son recursos que constituyen una
aplicación definida para una lógica de negocio completa.
Objetivos
 Comprender el funcionamiento de los componentes en las aplicaciones web.
 Conocer el uso e implementación de los tipos de llamadas entre las páginas web.
Tecnologías en J2EE:
La tecnología Enterprise JavaBeans (EJB) usa un modelo de componente para simplificar el
desarrollo de aplicaciones de middleware (capas) con soporte automático de servicios como
transacciones, seguridad y conectividad de base de datos.
JavaMail es una API que proporciona una serie de clases abstractas que modelan un sistema de
correo.
Java Message Service (JMS) es una API que permite el desarrollo de aplicaciones portables y
basadas en mensajes para la plataforma Java al definir un conjunto común de conceptos de
mensajería y estrategias de programación para todos los sistemas de mensajería compatibles con la
tecnología JMS.
JavaServer Faces (JSF) proporciona un modelo de programación que ayuda a crear aplicaciones Web
al ensamblar componentes reutilizables de interfaz de usuario en una página, al conectar esos
componentes a una fuente de datos de aplicación y conectar los eventos generados por los clientes
a manejadores de eventos en el servidor.
JavaServer Pages (JSP) permite que desarrolladores Web desarrollen rápidamente y mantengan
fácilmente páginas Web dinámicas e independientes de plataforma con interfaces de usuario
separadas y generación de contenido para que los diseñadores puedan cambiar el diseño de la
página sin cambiar el contenido dinámico. La tecnología usa etiquetas semejantes a las de XML que
encapsulan la lógica que genera el código para la página.
Standard Tag Library for JavaServer Pages (JSTL) es un conjunto de etiquetas personalizadas que
habilitan varias funciones comunes de Web sites en un formato estandarizado.
Los Java Servlets amplían y mejoran el alcance de los servidores Web al proporcionar un método
basado en componentes e independiente de plataforma para crear aplicaciones basadas en la Web
sin las limitaciones de rendimiento de los programas CGI.
La API Java Transaction (JTA) es una API de alto nivel, independiente de implementación y de
protocolo que permite que aplicaciones y servidores de aplicaciones accedan a transacciones Java
Transaction Service(JTS) especifica la implementación de un gestor de transacciones que soporta
JTA e implementa la correlación entre Java y la especificación OMG.

Componentes web en una aplicación Java EE


Definición de componente.
Una unidad de composición con interfaces especificadas de manera contractual y dependencias de
contexto completamente explícitas.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Un componente de software puede desplegarse independientemente y es sujeto de composición por
parte de terceros.
Los componentes de software posibilitan la reutilización de partes de software y la amortización de
inversiones a lo largo de múltiples aplicaciones.
Existen otras partes para su reutilización, tales como bibliotecas de código fuente, diseños o
arquitecturas.
Los componentes de software son unidades binarias de producción, adquisición y despliegue
independientes, que al interactuar, forman un sistema en funcionamiento.
Los puntos de acceso a los componentes permiten a los clientes acceder a los servicios
proporcionados por dicho componente.
Un componente puede tener varias interfaces, una por cada punto de acceso: uso, administración y
configuración. No conviene tener varias interfaces similares o redundantes.
La especificación de las interfaces es un contrato. El respeto de este contrato por cliente y
componente asegura el éxito de la interacción.
Modelos de componentes de Software
 Microsoft .NET (COM): Perspectiva PC
 SUN J2EE: Perspectiva Internet
 OMG CORBA Component Model: Perspectiva de corporaciones empresariales. Es un
superconjunto multi-lenguaje de la especificación EJB.
Los componentes más utilizados podemos diferenciarlos entre los siguientes
 Enterprise JavaBeans y el modelo de componentes de Java EE
 La estructura de componentes de .NET

La plataforma J2EE soporta un modelo de aplicación distribuida multinivel basado en componentes


escritos en Java:
 Componentes cliente: aplicaciones de cliente y applets
 Componentes web: servlets y JavaServer Pages (JSP)
 Componentes de negocio: Enterprise JavaBeans (EJB)
Los componentes J2EE pueden incluir componentes basados en JavaBeans, pero éstos no son
considerados parte de la especificación J2EE.
Objetivos por componentes de la arquitectura J2EE:
 Definir una arquitectura de componentes estándar para la construcción de aplicaciones
distribuidas basadas en Java
 Separar los aspectos de lógica de negocio de otros soportados por la plataforma:
transacciones, seguridad, ejecución multihilo y otros elementos de bajo nivel
 Filosofía java: Escribir una vez y ejecutar en cualquier parte
 Cubrir los aspectos de desarrollo, despliegue y ejecución del ciclo de vida de una aplicación.

Un contenedor es un proceso donde se ejecutan los componentes.


 Gestiona los componentes de la aplicación
 Ciclo de vida
 Proporciona acceso a servicios de la plataforma, como por ejemplo, transacciones, seguridad,
conectividad.
Cuando un desarrollador crea un modelo de arquitectura basado en la plataforma JEE, debe
especificar los siguientes elementos en el contenedor:
 Los componentes de la aplicación
o Servlets
o JSPs (Java Server Pages)
o EJBs (Enterprise Java Beans)
 Los descriptores de despliegue
o Ficheros XML que describen los componentes de la aplicación.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Servlets y JavaServer Pages (JSP) son los componentes del nivel de presentación.
Permiten generar páginas web dinámicas
Servlets: Utilizan el código Java puro. Más fácil de controlar el flujo de acciones.
JSP: Lenguaje de marcado basado en etiquetas, es más fácil representar información en el lado del
cliente.
Enterprise JavaBeans (EJB) es una completa especificación de arquitectura para componentes de
servicio.
Objetivos de la arquitectura de componentes EJB:
 Facilitar el desarrollo de aplicaciones, concentrándose en la lógica de negocio: desarrollo,
aplicación y aspectos de tiempo de ejecución.
 Lograr la independencia del proveedor de componentes mediante la especificación de
interfaces.
 Lograr independencia de la plataforma
 Asegurar la compatibilidad con Java-APIs existentes, con sistemas de servidor de terceros y
con protocolos de CORBA y de servicios Web.
Estructura de una aplicación JEE mediante componentes y contendores:

Envío de información request y response HTTP


Una aplicación web es una aplicación que trabaja en un servidor y sobre la que un usuario accede
desde un cliente general, como por ejemplo un navegador en un PC, un teléfono móvil o una PDA.
La comunicación en la Web gira en torno al protocolo http y sus características son las siguientes:
 Protocolo de nivel de aplicación
 Funciona sobre TCP
 Usa el puerto 80 por defecto
 Modelo petición/respuesta (request/response)
 No tiene estado
 Al igual que SMTP, es un protocolo ASCII, que usa MIME para transferir información no
ASCII.
 Tipos de peticiones: GET, POST, PUT, DELETE, TRACE, OPTIONS, HEAD

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Los dos tipos de peticiones más relevantes en aplicaciones web son GET y POST y se utilizan para
enviar información mediante dicho protocolo.
Una petición http mediante el método get envía los parámetros en la cabecera de la página del
servidor y dichos parámetros son visibles en la cabecera del navegador, es decir, el cliente puede
visualizar la información que se está enviando.

El formato estándar para peticiones http con el método get es la siguiente:

URL?dato1=valor1&dato2=valor2 ... &datoN=valorN


Podemos visualizar el ejemplo en una página HTML si escribimos el siguiente código:
<HTML>
<head>
<title>Enviar información GET</title>
</head>
<body>
<a href=“ http://www.midominio.com/paginadestino.html?ciudad=Paris&Pais=Francia”>
Enviar datos de ciudad
</a>
</body>
</HTML>
Hemos creado un enlace como se muestra en la imagen:

Y al pulsar sobre el enlace, podemos visualizar sobre la barra del navegador la información que está
enviando con el método GET.
http://www.midominio.com/paginadestino.html?ciudad=Paris&Pais=Francia

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Debemos tener en cuenta los siguientes parámetros al enviar caracteres en el valor de un
parámetro:
 Caracteres ASCII alfanuméricos y signos. (punto), - (guión), * (asterisco) y _ (subrayado)
son literales.
 Debemos sustituir los espacios en blanco por el símbolo +.
 Resto de caracteres son admitidos
Las sustituciones las debe realizar el desarrollador de la página que va a enviar la información
mediante GET.
Si un valor aparece repetido más de una vez en la cadena del envío, el parámetro correspondiente
es recibido como un vector de valores, por ejemplo:
<a href=”paginadestino.html?dato=Miami&dato=Londres&dato=Madrid”>
Enviar datos
</a>
En la recepción de la página de destino, los datos vendrán establecidos de la siguiente forma:
dato[0] = Miami
dato[1] = Londres
dato[2] = Madrid
Peticiones POST
El envío de información mediante el método POST es un envío oculto, los elementos que se envían
no se visualizan en el explorador y se utilizan para enviar la información de un formulario, no se
pueden enviar valores específicos tal y como hace get, sino que solamente envía los controles
existentes de un formulario HTML.
Los datos se envían como parámetros, pero éstos no forman parte de la URL, sino que se envían
como parte del cuerpo del mensaje.
El cliente (navegador) codifica automáticamente los valores de los parámetros asociados a un
formulario (tanto si se envía por POST como por GET).
Ejemplo de envío mediante POST:
<HTML>
<head>
<title>Enviar información POST</title>
</head>
<body>
<form action=“paginadestino.html” method=“POST”>
<table border="1">
<tr>
<td>
Ciudad: <input type=“text” name=“txtciudad”>
</td>
</tr>
<tr>
<td>
Pais: <input type=“text” name=“txtestado”>
</td>
</table>
<input type="submit" value="Enviar datos"/>
</form>
</body>
</HTML>

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Cuando enviemos la información, comprobaremos que nos lleva a la página de destino y que no
visualizamos los datos enviados en el protocolo http.
Al trabajar con tecnología JEE, el tipo de envío es esencial para la lógica de la aplicación, ya que
todos los elementos de servidor web tendrán que enviar información.

El modelo actual de páginas web, define que las peticiones de los clientes son solicitudes a páginas
de servidor (jsp, servlets…) que contienen la lógica de negocio y el diseño HTML en un mismo lugar.
Las páginas ejecutan acciones del usuario que ha realizado sobre esa página. Dichas acciones son
capturadas por clases o pueden estar escritas en una clase Servlet.
En este tipo de arquitectura conocida, el cliente hace Request a objetos de la capa de presentación
(Pagina del servidor), que luego llama a su código controlador para pedirle funcionalidad y devolver
una respuesta (response).
El método HTTP GET se utiliza cuando:
 El procesamiento de la solicitud es independiente a la información enviada, es decir, no es
necesario pedir datos al usuario mediante formularios.
 La solicitud no tiene efectos secundarios en el servidor.
 La cantidad de datos a enviar es pequeña.
 Se desea asignar un marcador a la solicitud.

El método HTTP POST se utiliza cuando:


 El procesamiento de la solicitud modifica el estado del servidor, como al almacenar datos en
una base de datos.
 La cantidad de datos del formulario es grande.
 El contenido de los datos no debe aparecer en la URL (por ejemplo, contraseñas).

Diferenciación entre información con servlets y JSP


Servlets
Los servlets son clases de Java que implementan la clase HttpServlet.
Dichos servlets no contienen parte gráfica, por lo que su funcionamiento en el momento de recibir
una petición no tiene por qué ser dar salida a código HTML en el cliente.
Un servlet se puede definir como un conjunto de acciones capturadas desde un cliente y que pueden
derivar en una respuesta http o pueden realizar un flujo de trabajo.
Aquí tenemos un ejemplo gráfico en el que podemos visualizar el funcionamiento de request y
response en un servlet.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El cliente, mediante el navegador, hace una solicitud al contenedor web, que captura dicha solicitud
en un servlet mediante un request.
El servlet puede enviar una respuesta mediante un objeto response, y dicha respuesta puede ser
implementada mediante un objeto PrintWriter para devolver código HTML que se generará de nuevo
en el cliente, pero como he comentado anteriormente, ese flujo HTML puede ser opcional de escribir
o no.
Un servlet no contiene parte gráfica, debe ir en un paquete y es código de Java puro implementando
la herencia de clases y sobreescritura de métodos.
Código de un servlet:
package NOMBREPAQUETE;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class NewServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Como podemos comprobar, un servlet es código puro de java, e implementa clases mediante
herencia y utiliza override para los métodos.
La llamada a un servlet se debe realizar a través de contenidos estáticos HTML, tales como páginas
HTML o jsp.

JSP (Java Server Pages)


Las páginas JSP contienen lógica de servidor y lenguaje HTML en un mismo conjunto. Teniendo en
cuenta esto, las páginas jsp contienen parte gráfica y lógica de servidor.
En realidad, las páginas JSP utilizan un servlet interno al que se accede mediante etiquetas de
servidor y que también implementan el diseño HTML.
Las páginas JSP son la evolución de los servlets y permiten realizar acciones más dinámicas que un
servlet, ya que podemos utilizar la lógica del servidor separada del diseño, pero en un mismo
conjunto.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Este gráfico muestra cómo se desarrolla la información en un servidor cuando se realiza una petición
a una página jsp con request.

Como vemos, la información pasa toda la información al servidor mediante la página jsp, pero dicha
información se mantiene en la propia página jsp, que llama a su vez a un fichero java que contiene
el servlet interno asociado a la página.
Código de una página JSP:
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Bienvenido a mi página JSP</h1>
<%
//CODIGO DE SERVIDOR
%>

</body>
</HTML>
Como podemos comprobar, la página JSP contiene código del servidor entre las etiquetas y, a
su vez, ofrece un diseño de página HTML, por lo que la creación de elementos dinámicos junto a
contenido estático es más eficiente, ya que la información HTML ya está escrita e implementada.

Ver Video: CrTipos de ficheros descriptores, en la Unidad 3, en


el Módulo 4, en la plataforma elearning

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 4. Desarrollando Servlets
Introducción
Un servlet es un componente web de J2EE desarrollado con el objetivo de procesar requerimientos
de un cliente o requests y generar respuestas con contenidos web dinámicos.
Para ser ejecutados es necesario la utilización de un servidor que de soporte a servlets y su
contenedor.
Por ejemplo, un servlet puede procesar los datos desde un formulario en HTML, mantener un
registro de la transacción, actualizar una base de datos, contactar algún sistema remoto y devolver
un documento dinámico o redirigir a otro servlet.
Los servlets son una buena opción como reemplazo a CGI, ya que proporciona una forma para
generar documentos dinámicos que contiene un mejor desempeño al procesar cada solicitud
request, tener acceso a las características de Java y sus extensiones, y poseer un manejo simple de
parámetros, cookies y sesiones.
Para entender qué son los servlets es necesario conocer su antecesor, los CGIs.
Objetivos
 Conocer la tecnología Java EE con las clases servlets.
 Implementar el código de servlets en profundidad para realizar acciones web.

CGI
Internet fue diseñada inicialmente para ser un depósito de datos estáticos guardados en páginas
HTML, sin embargo, rápidamente se introdujo la necesidad de poder proveer datos generados
dinámicamente.
La primera respuesta a esta necesidad fue Common Gateway Interface (CGI). Esta interfaz permite
a un servidor Web ejecutar programas en diversos lenguajes, de preferencia Perl, Delphi o C, al que
se le entregan datos desde un formulario HTML a través de la entrada estándar o de variables.
Después se procesan dichos datos con las capacidades que proporcione el lenguaje elegido, como
por ejemplo acceso a bases de datos, utilizar archivos, ejecutar programas externos, etc.
Finalmente, los resultados de la ejecución deben ser escritos en un formato adecuado hacia la salida
estándar que es direccionada al cliente.
Aun cuando CGI es una solución práctica tiene algunas limitaciones, que con el tiempo se han
tratado de minimizar, pero aún se mantienen.
Debido a la necesidad de crear un nuevo proceso para ejecutar un programa CGI cada vez que es
invocado, CGI se vuelve relativamente lento, en particular en los lenguajes interpretados, por lo que
no proporciona una buena escalabilidad.
Existen algunas soluciones a este problema como es el caso mod_perl para Perl sobre Apache, el
cual consiste en mantener un sólo intérprete en ejecución, que es compartido por todos los CGIs.
Esto soluciona el problema, pero obliga a ser más cuidadoso en la utilización de variables debido a
que los CGIs comparten el mismo ambiente.
El código utilizado para acceder a recursos del sistema, como archivos o bases de datos, son
específicos a la plataforma del servidor. Esto quiere decir que muchas aplicaciones no funcionarán al
trasladarse de servidor a menos que se realicen modificaciones en los códigos fuentes.
Las aplicaciones CGI se vuelven difíciles de mantener debido a que combinan contenidos y formas
de presentación en un solo código fuente, lo que hace necesario ser cuidados en ambos aspectos
para crear y modificar un CGI.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Se han hecho mejoras en este ámbito, en particular en Perl, como la creación de módulos que
permiten la utilización de plantillas o templates con el objeto de separar el manejo de datos de su
presentación.
No existe un método simple para mantener y compartir recursos entre distintos CGIs, lo cual
complica características como mantener sesiones de usuario o variables compartidas.
Como posibles soluciones se pueden utilizar archivos en el servidor que son modificados
concurrentemente, o guardar toda la información a compartir entre CGIs como datos en el cliente,
por ejemplo a través de cookies, sin embargo estas soluciones o son complejas, para el primer caso,
o son inseguras y restringidas en tamaño, para el segundo.

Ciclo de vida de un servlet


Los servlets son programas Java que se ejecutan en un contenedor Web dentro de un servidor de
aplicaciones y actúan como una capa intermedia entre la petición de un cliente y la aplicación del
servidor o la base de datos.
Un servlet puede:
 Leer los datos explícitos enviados por el cliente. Suele ser información introducida en un
formulario HTML.
 Leer los datos implícitos de la petición HTTP enviada por el navegador. La información HTTP
incluye las cookies, y toda la información que se incluye dentro de la cabecera de una
petición HTTP.
 Generar resultados. Este proceso puede requerir comunicarse con la base de datos, ejecutar
una llamada RMI, invocar un servicio Web o generar la respuesta directamente.
 Enviar datos explícitos al cliente. El documento puede ser enviado en una gran variedad de
formatos, ya sea HTML o XML, imágenes GIF o JPG, archivos EXCEL, etc.
 Enviar datos implícitos en la respuesta HTTP al cliente. La información HTTP incluye el
establecimiento de cookies y cualquier cabecera que pueda enviarse dentro de la respuesta
HTTP, como el almacenamiento en caché, etc.
Podemos resumir que un servlet se dedica a responder peticiones HTTP de los navegadores clientes
y a generar resultados dinámicos en respuesta a estas peticiones.
Los servlets no solo se limitan a responder peticiones HTTP. Existen servlets que pueden ser
embebidos en un servidor FTP o en servidores de correo, pero en la práctica solamente se utilizan
los servlets que responden peticiones HTTP.
Un servlet tiene un ciclo de vida bien definido, es decir, está especificado cómo y cuándo un servlet
debe ser cargado e instanciado en la memoria, inicializado, ejecutado y finalmente destruido.
Instanciación
El container de servlets es el encargado de cargar e instanciar cada servlet. Esto puede suceder en
la inicialización del container o después, hasta que el container determine que el servlet es necesario
para procesar un request.
Los archivos necesarios para ejecutar un servlet deben ser localizados por el container para poder
cargarlos utilizando el Java Class Loader que proporciona el lenguaje.
Inicialización
Después de que un servlet se haya instanciado, el container debe inicializar el servlet.
La inicialización permite a un servlet realizar tareas como leer datos persistentes de configuración,
crear recursos como conexiones a bases de datos, o cualquier tarea que deba ser ejecutada sólo una
vez previamente a interactuar con clientes.
Aunque los servlets se ejecutan en servidores multithreads, no existen problemas de concurrencia
durante su inicialización.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El container debe ejecutar sólo una vez el método de inicialización al crear la instancia del servlet y
no debe volver a hacerlo sin antes destruirlo previamente.
Interacción con Clientes
Después de ser inicializado, un servlet es utilizado para procesar peticiones (request) de diferentes
clientes.
Todos los requests que corresponden al mismo servlet son procesados por la misma instancia en
forma concurrente por lo que hay que tomar las medidas necesarias para evitar problemas en el
acceso a variables compartidas.
El container garantiza que si un servlet implementa la interfaz SingleThreadModel, sólo un thread a
la vez ejecutará el servlet, evitando de forma simple, pero menos óptima, estos problemas de
sincronización.
Destrucción
No es obligatorio que un container mantenga un servlet cargado por un período de tiempo
específico.
Cuando el container determina que un servlet debe ser destruido, que podría ser entre la
inicialización del servlet y el cierre del container, se ejecuta un método particular con el objetivo de
guardar configuraciones, cerrar conexiones, archivos, etc.
Cuando se encuentra en ejecución el método de destrucción, el container no debe aceptar nuevos
clientes para esa instancia, y una vez finalizado debe eliminar la referencia a la instancia con el fin
de ser eliminado por el recolector de basura de Java.
Gráfico del ciclo de vida de un servlet:

Estructura de un servlet
Los servlets heredan de la clase HttpServlet y sobreescriben el método doPost o doGet,
dependiendo de si los datos han sido enviados por el método POST o GET.
Los servlets no tienen una parte gráfica, sino que son clases que representan una petición de un
cliente, para posteriormente, ejecutar una serie de acciones o representar un código de salida HTML
como respuesta a la llamada.
Podemos realizar la misma acción tanto para peticiones GET y POST simplemente llamando a
doGet desde doPost o viceversa.
Ambos métodos, doPost y doGet, ofrecen dos argumentos:
 Un objeto HttpServletRequest: Encapsula la petición http
 Un objeto HttpServletResponse: Encapsula la respuesta HTTP.
El objeto HttpServletRequest nos permite acceder tanto a los datos como a las cabeceras de la
petición HTTP.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El objeto HttpServletResponse nos permite modificar la información de salida, como los códigos de
estado HTTP o las cabeceras de respuesta.

Además podemos obtener un objeto PrintWriter sobre el que generar el contenido dinámico del
documento al cliente.

Los métodos doGet y doPost pueden lanzar las excepciones ServletException e


IOexception por lo que deben controlar dichas excepciones, ya sea mediante throws o mediante
try-catch.
Código de los métodos doGet y doPost:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//IMPLEMENTACION DEL METODO CON ENVIO GET
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//IMPLEMENTACION DEL METODO CON ENVIO POST
}
Clases principales de servlets
Para poder trabajar con servlets, debemos importar los paquetes java.io (para el PrintWriter),
javax.servlet (para el HttpServlet) y javax.servlet.http (para el HttpServletRequest y
HttpServletResponse).
Los objetos para la definición de servlets se encuentran divididos en dos paquetes:
javax.servlet.*, que proporciona clases necesarias para crear servlets genéricos,
independientes del protocolo utilizado, y javax.servlet.http.*, que proporciona las clases que
definen un servlet específico para el protocolo HTTP.

Servlet define la funcionalidad básica que tiene un servlet como es su ciclo de vida (métodos init,
destroy) y procesar requests (método service).
Es implementado por la clase GenericServlet.

SingleThreadModel es una interfaz utilizada para marcar los servlets que se desea que se
ejecuten en forma secuencial por requests simultáneos, evitando posibles problemas de
procesamiento paralelo.

HttpServlet agrega la funcionalidad para procesar los variados tipos de request HTTP
(principalmente los métodos doGet, doPost para procesar formularios GET y POST,
respectivamente).

HttpServletRequest proporciona información del request del cliente al servlet a través del
protocolo HTTP. Se pueden obtener datos como encabezados, cookies y características genéricas
como dirección del cliente y parámetros recibidos desde él (getParameter). Permite también asociar
objetos (setAttribute) y acceder al objeto HttpSession.

HttpServletResponse asiste a un servlet para enviar una respuesta al cliente a través de un


canal de comunicación binario o de texto (getWriter). Provee también funcionalidad específica para
respuestas HTTP como enviar encabezados, cookies (addCookie) y errores con códigos numéricos
como 403 (sendError).

HttpSession permite identificar un usuario a través de más de una página, para esto se le asigna
un identificador único que se mantiene mientras el usuario navega en el sitio (getId). Permite
asignar un tiempo máximo de inactividad y se le pueden asociar objetos para compartir entre
servlets (setAttribute y getAttribute).
El código completo de cualquier servlet sería el siguiente:
package NOMBREPAQUETE;

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class NewServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Cualquier servlet debe tener un sistema de carpetas específico para poder ser ubicado en su
contenedor y su servidor.
Si visualizamos el entorno de carpetas dentro del IDE NetBeans, veremos los siguientes elementos:

La carpeta WEB-INF indica el fichero xml que contiene el descriptor de acceso, que indica los
servlets que están ubicados dentro de nuestra aplicación.
Tenemos una carpeta llamada Source Packages dónde irían los códigos de nuestras clases y de los
servlets. Es recomendable poner los servlets dentro de estructura de paquetes.
Por último, tenemos una carpeta llamada Web Pages dónde estarían las páginas web que realizarán
la llamada a los servlets.

Configuración de los Servlets mediante anotaciones y


descriptores
El descriptor de despliegue de una aplicación web (web.xml) es un archivo escrito en XML que
describe diversas características de la aplicación web.
Si utilizamos un contendor de servlets que implemente la especificación 3.0 de los servlets no es
necesario el uso del descriptor de despliegue. Podemos configurar los servlets mediante anotaciones
en el propio código fuente.
Los descriptores de despliegue indican al servidor que servlets contiene y el alias que se les ofrece
para su llamada. Si un servlet no está declarado en el fichero xml, la llamada puede estar bien
escrita en el código, pero el servidor será incapaz de encontrarlo.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Una plantilla para la descripción de servlets es la siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi=_
"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=_
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>NewServlet</servlet-name>
<servlet-class>PaqueteServlets.NewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>NewServlet</servlet-name>
<url-pattern>/NewServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
El primer elemento indica el inicio de la aplicación, es dentro de este elemento donde se
definen todos los elementos restantes.
El elemento define las características de un servlet y, a su vez, está compuesto por los
elementos y , que indican un nombre corto para el servlet así como el
nombre de la clase Java que contiene el servlet, respectivamente. La clase Java se indica con la
ruta completa de packages.
Posteriormente, se define el elemento para establecer la ubicación en términos de
URL.
Está compuesto por los elementos y que especifican el nombre del servlet
que será accesible a través de un patrón URL.
Otras de las características que podemos encontrar dentro del documento de despliegue son el
tiempo en minutos que durará la sesión de un usuario mediante la etiqueta y la
página inicial del servidor al realizar una petición mediante la etiqueta .

Uso de las APIs request y response en servlets


Vamos a visualizar la información que recibimos al ejecutar un código servlet.
Lo primero que vamos a hacer será implementar y visualizar la funcionalidad de un servlet en
ejecución.
Nos crearemos un proyecto nuevo en NetBeans.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Seleccionamos la carpeta Java Web y dentro de esta Web Application.

Le damos un nombre y una ruta dónde almacenaremos el proyecto.

Seleccionamos el servidor sobre el cuál vamos a trabajar con servlets, en nuestro ejemplo, yo he
seleccionado Apache Tomcar, pero podríamos seleccionar cualquier otro de la lista como GlassFish.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Le indicaremos que no vamos a utilizar ninguna tecnología nueva y pulsamos en Terminar.

Como podemos comprobar, nos ha creado un proyecto con una estructura de servidor como ya
hemos ido viendo en diferentes capítulos. Tenemos la carpeta WEB-INF con el descriptor de
despliegue, una carpeta llamada Web Page dónde irán incluidas todas las páginas Web del proyecto
JEE y una carpeta llamada Source Packages en la que crearemos nuestros servlets para utilizarlos
en las páginas.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Para crearnos y visualizar la funcionalidad de los servlets, debemos crearnos un nuevo paquete,
para ello, seleccionamos la opción Nuevo  Paquete Java sobre la carpeta Source Packages.

Indicamos el nombre del paquete, como por ejemplo paqueteservlets y pulsamos sobre Terminar.

Ahora vamos a crearnos nuestro servlet. Sobre el paquete ya creado, seleccionamos la opción
Nuevo  Servlet.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Le damos el nombre de PrimerServlet y pulsamos en siguiente. Nos aparecerá por defecto la
ubicación del paquete anterior, aunque podríamos cambiarlo por cualquier otro en este momento.
Pulsamos en Siguiente.

Esta pantalla indicará la información que vamos a incluir en el descriptor de despliegue. Por defecto
marcamos la opción “Add information to deployment descriptor” y dejamos los parámetros del
nombre y url pattern tal y como están.

Ahora vamos a escribir un código en el servlet que generará un mensaje como respuesta HTML.
Escribimos el siguiente código en el servlet PrimerServlet.
package paqueteservlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PrimerServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
out.println("<title>Servlet PrimerServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>CODIGO GENERADO DESDE EL SERVLET</h1>");
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Si nos fijamos en el descriptor de despliegue de la aplicación, veremos que se ha agregado la
información del servlet creado.
Sobre la carpeta WEB-INF, vemos el fichero web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-
app_2_5.xsd">
<servlet>
<servlet-name>PrimerServlet</servlet-name>
<servlet-class>paqueteservlets.PrimerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PrimerServlet</servlet-name>
<url-pattern>/PrimerServlet</url-pattern>
</servlet-mapping>
</web-app>
Ahora vamos a agregar una página HTML en el servidor que realizará la llamada al servlet.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Escribimos el siguiente código en la página HTML para realizar la llamada al servlet:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
</head>
<body>
<form name="form1" action="PrimerServlet">
<input type="submit" value="Llamar a servlet"/>
</form>
</body>
</HTML>
La línea más importante es la propiedad ACTION del formulario, que realiza la llamada al nombre del
servlet escrito en el descriptor de despliegue.
Para comprobar el funcionamiento del servlet, seleccionaremos sobre la página HTML la opción RUN
FILE. Dicha opción no sería necesaria si no utilizáramos tecnología de servidor, pero necesitamos
arrancar el servidor de aplicaciones para poder llamar al componente servlet.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Como podremos comprobar, inicia el servidor y podemos visualizar la información de la llamada al
servlet una vez pulsado el botón de la página HTML.

Métodos de información del servidor con servlets


Los servlets pueden obtener información del servidor, ya sean datos propios del servidor dónde
están trabajando, o mediante el envío de información desde un formulario HTML por parte de la
solicitud de una página.
Para obtener información sobre el servidor en el que el servlet está trabajando, tenemos los
siguientes métodos:
Nombre del servidor
 request.getServerName()
Número de puerto
 request.getServerPort()
Los servlet también pueden obtener información general sobre el servidor:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Software del servidor:
 getServletContext().getServerInfo()
El servlet puede obtener información del cliente sobre la petición request:
Obtener la dirección IP del cliente
 request.getRemoteAddr()
Obtener el nombre del cliente Host
 request.getRemoteHost()
Una petición puede estar acompañada de un número arbitrario de parámetros. Los parámetros se
pueden enviar desde formularios HTML y son una de las bases de la difusión de la información en el
servidor.
 GET como una cadena añadida a la URL
 POST como datos que no aparecen en la URL
El método String getParameter(“nombreParámetro") devuelve el valor asociado al objeto que se ha
denominado como nombreParámetro en la petición. Tenemos que tener en cuenta que se diferencia
entre mayúsculas y minúsculas. Devuelve null si no aparece dicho parámetro en la petición.
Funciona igual para peticiones GET y POST.
 Método getParameterValues("NombreParametros")

† Devuelve un array de valores para todas las ocurrencias del nombre del parámetro en la cadena
de petición y null si no aparece. Se utiliza, por ejemplo, para capturar objetos que forman
conjuntos en un formulario, como puede ser un grupo de radiobutton HTML.
 getParameterNames( )

† Devuelve una enumeración de los parámetros de petición sin ningún orden.


Vamos a visualizar un ejemplo en el que recuperaremos información de una página HTML en un
servlet mediante un formulario.
Sobre un paquete creado en NetBeans, añadimos un nuevo servlet llamado ServletInformacion.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora, sobre la carpeta Web Pages, agregamos una nueva página web y la llamaremos
datosusuario.

Sobre la página datosusuario.html creamos un formulario que llamará al servlet que recibirá la
información. Escribimos el siguiente código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
</head>
<body>
<form name="form1" action="ServletInformacion">
<table border="1">
<tr>
<td>
Nombre
</td>
<td>
<input type="text" name="txtnombre"/>
</td>
</tr>
<tr>
<td>
Edad
</td>
<td>

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
<input type="text" name="txtedad"/>
</td>
</tr>
<tr>
<td>
Direccion
</td>
<td>
<input type="text" name="txtdireccion"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Enviar datos"/>
</td>
</tr>
</table>
</form>
</body>
</HTML>
Ahora vamos a implementar el código del servlet para que recupere la información de la página
mediante request.getParameter(). Escribimos el siguiente código en el servlet:
package paqueteservlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletInformacion extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String nombre, edad, direccion;
nombre = request.getParameter("txtnombre");
edad = request.getParameter("txtedad");
direccion = request.getParameter("txtdireccion");
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Recepción de información</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Datos recibidos</h1>");
out.println("<h4>Nombre: " + nombre + "</h4>");
out.println("<h4>Edad: " + edad + "</h4>");
out.println("<h4>Dirección: " + direccion + "</h4>");
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Al ejecutar la aplicación, veremos que la información es enviada al servidor y que podremos recibirla
en nuestro servlet:

Al pulsar el botón, veremos que el servlet nos genera un código HTML de salida con los parámetros
recibidos.

Ver Video: Eliminar datos con servlets, en la Unidad 4, en el


Módulo 4, en la plataforma elearning

Laboratorio 1: Consulta de empleados


Objetivos
 Aprender a manejar los servlets con acceso a datos.
 Escribir código HTML desde la petición de un servlet.

Enunciado
Vamos a realizar un servlet que devolverá una lista de empleados a partir de su nombre.
Realizaremos un buscador en una página HTML que realizará la llamada al servlet y escribiremos
una tabla con los empleados encontrados como resultado de la operación.
Lo primero que vamos a realizar será crearnos un nuevo proyecto Web Application.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Le daremos el nombre de ProyectoServlets.

Utilizaremos el servidor Glassfish por defecto.

No implementaremos ningún Framework.

A continuación, nos crearemos un nuevo paquete. Pulsaremos sobre la carpeta source packages y
seleccionaremos la opción Java Package.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Le daremos el nombre paqueteservlets

Sobre nuestro nuevo paquete creado, seleccionaremos crear nuevo servlet.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo llamaremos BuscadorEmpleados

Agregaremos la información del servlet al descriptor de la aplicación

Lo que debemos realizar ahora es el acceso mediante JDBC a la tabla EMP de Oracle. Para ello,
debemos agregar dentro de la carpeta Libraries el conector JDBC para Oracle.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ya podemos implementar el código en el servlet para que reciba un texto que llamaremos apellido y
devuelva una tabla con todos los empleados que coincidan con dicho apellido.

package paqueteservlets;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BuscadorEmpleados extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet BuscadorEmpleados</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Laboratorio Buscador de Empleados</h1>");
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","system", "12345");
Statement stmt = conn.createStatement();
String apellido = request.getParameter("apellido");
String consulta = "SELECT * FROM EMP WHERE UPPER(ENAME) ";
consulta += "LIKE '" + apellido.toUpperCase() + "%'";
ResultSet rs = stmt.executeQuery(consulta);
out.println("<table border='1'>");
while(rs.next()){
out.println("<tr>");
out.println("<td>");
out.println(rs.getString("ENAME"));
out.println("</td>");

out.println("<td>");
out.println(rs.getString("JOB"));
out.println("</td>");

out.println("<td>");
out.println(rs.getString("SAL"));
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
out.println("</td>");

out.println("<td>");
out.println(rs.getString("DEPTNO"));
out.println("</td>");
out.println("</tr>");
}
out.println("</table>");

out.println("</body>");
out.println("</HTML>");
}catch (Exception ex){
out.println("<h1>Excepcion "+ex.toString()+"</h1>");
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Ahora vamos a agregar una página HTML para poder realizar la llamada al servlet enviando el dato
del apellido.

La llamaremos paginabuscador.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Escribiremos el siguiente código para llamar al servlet:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
</head>
<body>
<form name="form1" action="BuscadorEmpleados">
Introduzca un apellido a buscar
<input type="text" name="apellido">
<br>
<input type="submit" value="Buscar Empleados">
</form>
</body>
</HTML>
Ya podremos ejecutar nuestro proyecto y comprobar el funcionamiento correcto de la aplicación:

Y como vemos el resultado de la llamada es el esperado:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Laboratorio 2: Modificar Departamento
Objetivos
 Aprender las consultas de acción en servlets con envío de parámetros.
 Conectar datos con JDBC.
Enunciado
Vamos a realizar un servlet que modificará los datos de un departamento que será enviado
dinámicamente desde una lista.
Lo primero que vamos a realizar será crearnos un nuevo proyecto Web Application.
Si ya hemos realizado prácticas anteriores, podemos saltarnos los pasos de creación de proyecto y
creación del paquete de servlets.

Le daremos el nombre de ProyectoServlets.

Utilizaremos el servidor Glassfish por defecto.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
No implementaremos ningún Framework.

A continuación, nos crearemos un nuevo paquete. Pulsaremos sobre la carpeta source packages y
seleccionaremos la opción Java Package.

Le daremos el nombre paqueteservlets

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sobre nuestro nuevo paquete creado, seleccionaremos crear nuevo servlet.

Lo llamaremos ModificarDepartamentos.

Agregaremos la información del servlet al descriptor de la aplicación

Lo que debemos realizar ahora es el acceso mediante JDBC a la tabla EMP de Oracle. Para ello,
debemos agregar dentro de la carpeta Libraries el conector JDBC para Oracle.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ya podemos implementar el código en el servlet para que reciba los datos del departamento a
modificar. Para ello, recibiremos tres datos, el número del departamento (txtnumero), el nombre
del departamento (txtnombre) y la localidad del departamento (txtloc).
package paqueteservlets;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*;

public class ModificarDepartamentos extends HttpServlet {

protected void processRequest(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet ModificarDepartamentos</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Laboratorio Modificar Departamentos</h1>");
String numero, nombre, loc;
numero = request.getParameter("txtnumero");
nombre = request.getParameter("txtnombre");
loc = request.getParameter("txtloc");
String consulta = "UPDATE DEPT SET DNAME=?";
consulta += ", LOC=? WHERE DEPTNO=?";
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","system", "12345");
PreparedStatement st = conn.prepareStatement(consulta);
st.setString(1, nombre);
st.setString(2, loc);
st.setInt(3, Integer.parseInt(numero));
int registrosafectados = st.executeUpdate();
conn.commit();
out.println("<h4>Modificación realizada correctamente</h4>");
out.println("<h1>Registros modificados "+registrosafectados+"</h1>");
}catch (Exception ex) {
out.println("<h1>Excepcion "+ex.toString()+"</h1>");

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
} finally {
out.println("</body>");
out.println("</HTML>");
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Ahora vamos a agregar una página HTML para poder realizar la llamada al servlet enviando todos los
datos de un departamento.

La llamaremos cambiardepartamento.

Escribiremos el siguiente código para llamar al servlet:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
</head>
<body>
<form name="form1" action="ModificarDepartamentos">
<table border="1">

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
<tr>
<th>Numero</th>
<td>
<input type="text" name="txtnumero">
</td>
</tr>
<tr>
<th>Nombre</th>
<td>
<input type="text" name="txtnombre">
</td>
</tr>
<tr>
<th>Localidad</th>
<td>
<input type="text" name="txtloc">
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Modificar Departamento">
</td>
</tr>
</table>
</form>
</body>
</HTML>
Ya podremos ejecutar nuestro proyecto y comprobar el funcionamiento correcto de la aplicación:

Y como vemos el resultado de la llamada es el esperado:

Si consultamos la base de datos, podremos comprobar el cambio:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 5. Desarrollando con la tecnología de
páginas JSP

Introducción
El estándar HTML propone el suministro de información mediante páginas estáticas.
De esta forma es imposible suministrar páginas creadas al momento en base a requisitos del cliente,
como por ejemplo, consultar una base de datos desde una página HTML y obtener otra página
automáticamente sólo con los resultados deseados.
Anteriormente a las páginas JSP, se utilizaron tecnologías en Java tales como CGI o servlets, pero la
tecnología servlets no implementa código HTML, sino que la solicitud por parte de un cliente se
realiza a código lógico de una clase Java.
Un Servlet podría verse como una herramienta que nos permite generar HTML desde código Java.
Una de las partes más tediosas de la programación de Servlets es precisamente la generación del
código HTML.
En una web real, especialmente si queremos que tenga una apariencia razonablemente buena,
tendremos que generar cantidades de HTML mayores. Si hacemos esto desde un Servlet, será
increíblemente tedioso.
Los Servlets son una herramienta pésima para crear la capa de presentación de la aplicación web, lo
que quiere decir que para generar el código HTML que el usuario visualizará finalmente se va a
renderizar en el navegador web del usuario.
Las páginas JSP son código HTML que tiene código Java empotrado, pero su mayor característica es
que son principalmente código HTML, por lo que simplemente tendríamos que empotrar pequeñas
cantidades de código Java para crear sus partes dinámicas
Otras tecnologías que compiten con Java Server Pages son ASP y PHP.
Las principales ventajas de JSP son:
 Mayor encapsulación:
 Uso de clases
 Uso de JavaBeans
 Mayor escalabilidad
 Uso de tags: similitud con HTML
 Mayor portabilidad
 Uso de un lenguaje estándar y muy difundido
El lenguaje en que actualmente está basado JSP es Java
Realmente una página JSP se convierte en un servlet que es quien se encarga de la comunicación
con el cliente
El funcionamiento básico de una página JSP es muy sencillo:
1) El cliente solicita una página jsp
2) La solicitud llega al servidor
3) El servidor «ejecuta» la página jsp y obtiene un texto formato HTML
4) El servidor envía el texto HTML al cliente
5) El navegador del cliente visualiza el texto HTML como realmente hubiera estado almacenado
en el servidor
Objetivos
 Conocer la evolución de la tecnología Servlet a páginas de servidor JSP.
 Comprender el funcionamiento de etiquetas custom tags y la creación de páginas dinámicas
con código Java.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Características de Java Server Pages
Las páginas JSP se sitúan dentro de un proyecto Java EE de un modo similar a las páginas HTML
estáticas, es decir, en desarrollo suelen estar colgando de la raíz de un directorio con nombre "web"
(en Netbeans dentro de Web Pages), posiblemente organizadas en una estructura de directorios
adecuada para nuestra aplicación.
A menudo no querremos que un usuario pueda llegar directamente una página JSP.
Puede que esa página esté preparada, por ejemplo, para recibir los datos de un formulario.
O que la página suponga que habrá algún dato guardado en la sesión del usuario.
Sin embargo, si publicamos la página JSP como cualquier otra página HTML estática, nada le va a
impedir al usuario teclear en su navegador la URL correspondiente con la página y acceder a ella
directamente.
Con las páginas HTML estáticas, esto no suele ser un problema. Con las páginas JSP, esto podría dar
lugar a un error en la aplicación porque la página ha sido accedida de un modo que no estaba
previsto.
Las páginas JSP no necesitan incluir ningún tipo de información en el descriptor de despliegue de la
aplicación, la URL que permite acceder a ellas es simplemente la misma URL que permitiría su
acceso como si se tratase de un recurso estático.
La estructura de cualquier página JSP es la siguiente:
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>La fecha actual es: <%=new java.util.Date()%> </h1>
</body>
</HTML>
Como podemos observar, el código de la página es prácticamente idéntico al de una página HTML.
La única diferencia es la etiqueta
Esta etiqueta, como veremos más adelante, se emplea para incluir dentro del documento HTML una
expresión Java, que será transformada en una cadena de caracteres invocando a su método
toString() para representar la hora del servidor dónde está ubicada la página, no del cliente que
accede a la página.
La forma de acceder a esta página sería igual a si fuese un recurso estático HTML, es decir,
podemos hacerlo a través de la URL:
http://localhost:8080/WebApplication1/paginaJSP.jsp
Las páginas JSP son componentes web que requieren un contenedor que les proporcione servicios.
No existe un contenedor especial, usa el mismo que los servlets, el Web Container.
El soporte para JSPs se implementa mediante un servlet que proporciona servicios a las JSPs.
Las páginas JSPa son traducidas a servlets y compiladas automáticamente por el contenedor.
Las JSPs corren como servlets dentro del contenedor.
El contenedor reconoce cuando se modifica una JSP y la recompila automáticamente.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Las ventajas de las páginas jsp son las siguientes en cuanto a rendimiento y programación:
Rendimiento.
 Igual que los servlets en momento de ejecución.
 Traducción y recompilación automática
 Proceso del lado del servidor.
Programación.
 Énfasis en componentes reutilizables.
 Portabilidad de plataforma.
 Separación de contenido estático y dinámico.
 Se extienden fácilmente mediante tag libraries.
 Lenguaje java con todas sus ventajas.

Elementos dentro de Java Server Pages


Existen cinco elementos de script diferentes que podemos encontrar dentro de las páginas JSP:
 Comentarios
 Directivas
 Declaraciones
 Expresiones
 Scriptlets.
Comentarios
Existen dos tipos diferentes de comentarios que podemos incluir en las páginas JSP.
El primer tipo es el comentario HTML estándar:
<!--comentario en código HTML-->
Este mensaje se envía al ordenador del usuario cuando realiza la petición, aunque no se renderiza
(como todos los comentarios HTML).
Estos comentarios también serán incluidos dentro del código del Servlet que será generado a partir
de la página JSP.
El otro tipo de comentario es el comentario de página JSP:
<%-- Comentario de página JSP-- %>
Estos comentarios sólo se ven en las páginas JSP.
No se incluyen en el Servlet durante la fase de producción, ni se envían al navegador del usuario.
Este tipo de comentario es el comentario Java, dónde sea posible escribir código Java en el cuerpo
de la página JSP también será posible escribir un comentario Java.
Estos comentarios se traducen al código fuente del Servlet que se generará a partir de la página
JSP, pero no se envían al usuario cuando realiza una petición.
Etiquetas de declaración
Dentro de una página JSP podemos incluir declaraciones de variables instancia, que estarán
accesibles desde todo el código de la página JSP. También podemos incluir declaraciones de
métodos.
Para realizar dicho tipo de declaraciones, se utilizan los que se llaman etiquetas de declaración:
Declaración de una variable:
<%! int numero = 0;%>
Declaración de un método:
<%! public String GetFecha() {

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
return (new java.util.Date()).toString();
}%>
Etiquetas Scriptlet
Todo el código HTML que incluyamos dentro de la página JSP, así como las etiquetas de scriptlet,
van a ser copiados a un método con nombre _jspService() del Servlet que se va a generar a partir
de nuestra página JSP.
Los scriptlets, al igual que el código HTML, son copiados al método _jspService(), pero son
considerados código Java y por tanto no se representan en el cliente.
Su funcionalidad es incluir la lógica de la página mediante el código java y pueden incluir cualquier
sintaxis válida de java.
Su sintaxis es:
<% numero += 10; %>
Como podemos comprobar, son acciones que escribimos cómo lógica de java. También podemos
incluir código java entre etiquetas HTML.
<% if (numero%2 == 0) { %>
<p>El número es par!!!</p>
<% } else { %>
<p> El número es IMPAR!!!</p>
<% } %>
En este código, estamos realizando la salida de código HTML dependiendo de un código Java.
Solamente mostrará uno de los dos mensajes que tenemos en el código HTML, dependiendo de la
lógica de nuestro código, que en este caso, mostraría si un número es par o es impar.
Etiquetas de expresiones
Las etiquetas de expresiones van a incluirse en la salida generada por los Servlet, combinándose
con el HTML que tienen alrededor empleando el operador "=" en el código del Servlet.
Su sintaxis es la siguiente:
<%= expresión Java %>
Por ejemplo:
<p> El resultado de multiplicar 5*4 es: <%= 5*4 %> </p>
Si en la expresión incluimos un objeto Java, como sucede siempre que se concatena una cadena de
caracteres con un objeto Java, se invocará a su método toString(), como por ejemplo, un objeto
Date:
<p> La hora actual es: <%= new java.util.Date() %> </p>
Podemos combinar etiquetas scriptlets con etiquetas de expresiones para ir representando la salida
que deseamos en el código HTML del cliente:
<%for (int i=1;i<6;i++){%>
<input type="text" value="<%=i%>">
<br>
<%}%>
De esta forma, estaríamos dibujando cinco cajas de texto en la página.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Etiquetas de directivas
Contienen información de configuración de la página JSP.
Dichas etiquetas no generan salida y normalmente se sitúan al principio de la página.
Su sintaxis es:
<%@ directiva [atributo= "valor"] % >
Existen tres tipos de directivas diferentes:
 page
 include
 taglib

Directiva Page
Esta directiva modifica la forma en la que se traduce la página JSP a un Servlet.
Puede tomar diferentes atributos, aunque sólo puede aparecer una vez cada atributo dentro de una
misma página JSP, a excepción del atributo import.
Este atributo se emplea para indicar que la clase necesita importar un paquete o clase:
<%@ page import= "java.util.Date" % >
Es posible indicar con una única directiva que se deben importar varios paquetes:
<%@ page import= "java.util.*, java.text,java.sql.Date" % >
La directiva Page contiene los siguientes atributos:
 language: Lenguaje de script (Java.)
 sesión: Especifica si la página participa en una sesión (true o false)
 buffer: Stream para objeto out.
 errorPage: define una URl para una página de error. (/error.jsp)
 import: Lista de los paquetes accesibles.(Genera postulados import de Java.)
 isErrorPage: Especifica si la página es una página de error. (true o false)
 isThreadSafe: Especifica el modelo de Thread. (true o false)
 contentType: formato de los datos. (text/HTML)
 info: String de información para identificar la página JSP.
 autoFlush: Determina que hacer cuando se llena el buffer.(true o false)
Ejemplos:
<%@ page isThreadSafe= "false" % >
<%@ page errorPage= "Error.jsp" %>
<%@ page session= "false" % >
Directive Include
La directiva include permite incluir un fragmento de código HTML o de página JSP dentro de otra
página JSP.
Los fragmentos, como su propio nombre indican, son fragmentos de HTML o de páginas JSP, pero
no páginas completas.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Son fragmentos que pueden ser empotrados en una determinada sección de una página JSP.
En muchos portales, existe contenido repetitivo como un pie de página con información de copyright
o de contacto, los menús, la cabecera, etc.
La idea de esta directiva es incluir este contenido que se repite en múltiples páginas en un fichero
independiente, y empleando esta directiva incluir dicho contenido en cada una de las páginas que lo
vayan a utilizar.
De este modo, cuando es necesario modificar ese contenido basta con modificar el fichero
independiente y no es necesario modificar todas las páginas donde aparece.
Su sintaxis:
<%@ include file="footer.jsp" %>
Vamos a ver un ejemplo completo de su funcionalidad:
Nos creamos una página HTML llamada header.html que contendrá el siguiente código:
<body>
<h1>Pagina Header</h1>
<img src="banner.jpg">
<a href="http://www.direccionweb.com">
Ir a direccion web
</a>
</body>
Después, escribimos el siguiente código en una página JSP:
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<%@ include file="header.html" %>
<h1>Pagina JSP</h1>
<%! int numero = 0;%>
<%for (int i=1;i<6;i++){%>
<input type="text" value="<%=i%>">
<br>
<%}%>
</body>
</HTML>
Y el resultado es el siguiente:

Directiva taglib

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Dicha directiva extiende el conjunto de tags que interpreta el contenedor web.
Sus características más importantes son:
 Asocia un prefijo con una biblioteca de tags.
 Una biblioteca de tags es un conjunto de programas Java que contienen métodos asociados
con los tags de la página JSP.
 Los tagslibs son elementos que se utilizan en tecnologías como custom tags o jstl de Java EE.
Por ejemplo:
<%@ taglib uri="TagLibrary" prefix="pref" %>

Variables implícitas en las páginas JSP


El contenedor de Servlets hace que todas las páginas JSP tengan acceso en las etiquetas de
expresión y en las etiquetas de scriptlet a un conjunto de variables que representan objetos que, a
menudo, son necesarios para generar la respuesta del usuario, como por ejemplo el objeto
correspondiente con la sesión del usuario, o el objeto HttpRequest o HttpResponse.
Estas variables implícitas simplemente son accesibles cuando estamos escribiendo código dentro de
una página JSP gracias al servlet que contienen embebido.
Las variables implícitas son las siguientes:
 application: objeto de la clase javax.servlet.ServletContext que se corresponde con el objeto
ServletContext de esta aplicación.
 config: objeto de tipo javax.servlet.ServletConfig que se corresponde con el objeto
ServletConfig.
 exception: objeto de la clase java.lang.Throwable que se corresponde con una excepción que
fue lanzada en una página JSP que tenía especificada como página de error la página actual.
Esta variable implícita sólo está presente en aquellas páginas JSP que hayan indicado que
isErrorPage= "true" empleando la correspondiente directiva de page.
 out: objeto de tipo javax.servlet.jsp.JspWriter; este objeto se corresponde con el flujo de
salida que se va a enviar al usuario.
 page: objeto de tipo java.lang.Object que se corresponde con la propia página JSP. Esta
variable implícita es equivalente a "this" en Java.
 PageContext: objeto de la clase javax.servlet.jsp.PageContext que define un ámbito igual a la
propia página.
 request: objeto de la clase javax.servlet.HttpServletRequest que se corresponde con el
objeto petición del usuario.
 response: objeto de la clase javax.servlet.HttpServletResponse que se corresponde con el
objeto respuesta.
 session: objeto de tipo javax.servlet.http.HttpSession que se corresponde con la sesión del
usuario.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Que estas variables se encuentren disponibles, resulta muy útil para el desarrollador, debido a que
no será necesario implementar ningún código adicional para obtenerlas.
Vamos a visualizar el uso de las variables en un código de página JSP.
Lo que haremos será una nueva página que enviará datos del usuario y escribirá los datos del
usuario en una tabla al enviar una petición.
Nos crearemos una nueva página JSP:

Escribimos el siguiente código en la página JSP:


<%@page import="java.util.Date"%>
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Ejemplo JSP variables internas</h1>
<form name="form1">
Nombre: <input type="text" name="txtnombre"><br>
Apellidos: <input type="text" name="txtapellidos"><br>
Fecha de nacimiento: <input type="text" name="txtfecha">
<input type="submit" value="Mostrar Datos">
</form>
<%
String nombre, apellidos, fechanacimiento;
nombre = request.getParameter("txtnombre");
apellidos = request.getParameter("txtapellidos");
fechanacimiento = request.getParameter("txtfecha");
if (nombre != null)

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
{%>
<h4>Los datos enviados son:</h4>
<table border="1">
<tr>
<th>Nombre: </th>
<td><%=nombre%></td>
</tr>
<tr>
<th>Apellidos: </th>
<td><%=apellidos%></td>
</tr>
<tr>
<th>Fecha Nacimiento </th>
<td><%=fechanacimiento%></td>
</tr>
</table>
<%}
%>
</body>
</HTML>
Nada más arrancar la aplicación, veremos que no dibuja ninguna tabla porque no hemos realizado
ningún envío sobre la página:

Al pulsar sobre el botón, podremos comprobar que utilizamos la variable implícita request y que la
información es recibida en el servidor y podemos escribirla:

Action Tags
Los Action Tags son etiquetas con formato XML que se incluyen dentro de las páginas JSP y que se
pueden utilizar dentro de dichas páginas JSP para llevar a cabo distintas acciones en tiempo de
ejecución.
Dichas acciones son un “acceso directo” a tareas usuales dentro de las páginas JSP y que podrían
realizarse sin necesidad de utilizar tags, pero es mucho más cómodo utilizar las etiquetas.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Su propósito es tratar de reducir la cantidad de código Java necesario dentro de una página JSP, así
como permitir que sea posible crear páginas JSP compuestas (idealmente) de un modo completo por
etiquetas.
Por lo tanto, estas etiquetas resultan más compactas y prácticas de usar que el código Java. No
obstante, todas las acciones que permiten realizar las etiquetas de las acciones estándar JSP podrían
conseguirse escribiendo código Java dentro de las páginas JSP.
Las características más importantes de las action tags son las siguientes:
 Proporcionan funcionalidad adicional para el desarrollador de la página JSP.
 Usan tags estilo XML.
 Parejas atributo/valor.
 Se pueden crear otros usando tag libraries.
 Pueden modificar el output stream.
 Usan, modifican o crean objetos.
 También se conocen como standard tags.

Los principales action tags son:


 jsp:useBean
 jsp:getProperty
 jsp:setProperty
 jsp:include
 jsp:forward
 jsp:param

Sirve para para crear o utilizar una instancia de un Java Bean.


Accesible dentro de un scope definido.
Si no existe un objeto con la misma variable de referencia, se instancia.
Si ya existe, se vuelve a usar la variable.
Tipos de sintaxis:
<jsp:useBean id="nomBean" scope="scope" class = "clase" />
<jsp:useBean id="nomBean" scope="scope" class = "clase" >
<% código para inicialización %>
</jsp:useBean>
Los tipos de Scope de la etiqueta useBean son:
scope puede ser:
 page: La instancia se mantiene solamente para la página
 request: La instancia se utiliza en la petición
 sesión: La instancia se mantiene dentro del objeto session y puede ser utilizan en otras
páginas.
 application: La instancia se mantiene dentro del objeto application y tiene el mismo valor
para todos los usuarios.
Por ejemplo, un Bean que se recupera a partir de un request de session:
<jsp:useBean id="mibean" scope="session" class="MiBean" >
<% mibean.init(request.getSession()); %>
</jsp:useBean>

Obtiene el valor de una propiedad de un Bean definido previamente con el tag


<jsp:useBean>.
Sintaxis

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
<jsp:getProperty name="nombreBean" property="nombrePropiedad" />
Ejemplo:
<jsp:useBean id="mibean" scope="page" class="MiBean" >
<jsp:getProperty name="mibean" property="MiPropiedad" />

Establece el valor de una propiedad de un Bean definido previamente con


<jsp:useBean>.
Sintaxis:
<jsp:setProperty name="nombreBean" expresión />
Donde el tipo de expresión puede ser:
<jsp:setProperty property="NombrePropiedad" [param="NombreParametro" |
value="ValorPropiedad"]>
Ejemplo:
<jsp:setProperty property="Apellidos" param="txtapellidos" >
Si no escribimos el nombre del parámetro y el valor, se asume que el nombre del parámetro es el
mismo que el nombre de la propiedad.
Ejemplo
<input type=”text” name=”Apellidos”>
<jsp:setProperty property="Apellidos">
Si se especifica property = "*" todas las propiedades del bean adquieren los valores
correspondientes de los parámetros del request.
<input type=”text” name=”Apellidos”>
<input type=”text” name=”Nombre”>
Presuponemos que en el Bean hemos declarado dos propiedades, llamadas Apellidos y Nombre.
<jsp:setProperty property="*">

Incluyen recursos dinámicamente en el momento de ejecución de la página JSP.


Sintaxis 1:
<jsp:include page="url" />
Sintaxis 2:
Incluimos un recurso en nuestra página y enviamos información en forma de parámetro a dicho
recurso.
<jsp:include page="url" >
<jsp:param name="nombre" value="valor" />
</jsp:include>

Pasa el control a otro recurso en forma incondicional.


<jsp:forward>
redirecciona la página actual a otra página que hayamos escrito en su propiedad page.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sintaxis 1:
<jsp:forward page="url" />
Sintaxis 2:
Podemos enviar información a la página que estamos redireccionando en forma de parámetro con la
etiqueta
<jsp:param>
<jsp:forward page="url" />
<jsp:param name="nombre" value="valor" />
</jsp:forward>
Existe otras etiquetas action tag, pero no se suelen utilizar.
 jsp:plugin genera información para Applets.
 jsp:fallback genera texto alterno si no hay soporte Java en el browser (usado con
jsp:plugin).
 jsp:text transmite datos de patrones.
 jsp:output modifica las propiedades del objeto output.
 jsp:root especifica el elemento raíz de una página JSP.
Por ejemplo, vamos a visualizar como utilizar un Bean en una página jsp y utilizar las etiquetas
action tags.
Para ello, nos vamos a crear una nueva clase en un proyecto.
Sobre la carpeta Source Packages agregamos una nueva Java Class.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Escribimos el siguiente código en la clase:
package paquetebeans;
import java.util.*;
import java.text.*;
public class PrimerBean {
private Calendar hora;
private Date horaactual;
private DateFormat formato;
private String cadhora;

public String Hora(){


horaactual= Calendar.getInstance().getTime();
formato= DateFormat.getTimeInstance();
cadhora=formato.format(horaactual);
return cadhora;
}
}
Ahora nos vamos a crear una nueva página JSP que implemente dicho bean y lo utilice para mostrar
la hora del servidor.

Implementamos el siguiente código para realizar la llamada al Bean:


<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<jsp:useBean id="objeto" scope="session" class="paquetebeans.PrimerBean"/>
<center>
<h1>HORA DEL SISTEMA <%=objeto.Hora()%></h1>

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
</center>
</body>
</HTML>
Y el resultado es el siguiente:

Custom Tags
Son etiquetas personalizadas que no las suele realizar el programador, sino el analista programador.
Uno de los grandes objetivos, es que el programador que lo vaya a utilizar, bastaría con que supiese
HTML para poder implementar la funcionalidad.
Un Custom Tag es una etiqueta propia, personalizada, es una ampliación de las Acciones JavaBeans.
Uno de los objetivos, será no utilizar en las páginas JSP código java, sino que los Custom Tags se
encargan de realizar todos los posibles tipos de acciones.
Se necesitan múltiples ficheros para trabajar: XML y JSP
Definición de etiquetas:
 Archivo tld  Es el archivo de definición de las etiquetas Custom Tags
 Debemos indicar las características de etiquetas que habrá en todo mi proyecto.
 El fichero Xml es la descripción de nuestro sitio web
 El fichero class  es la clase con la lógica java
 El fichero JSP  La página para mostrar las etiquetas Custom tags.
Necesitamos un fichero descriptor de la estructura de etiquetas que contenga una serie de
argumentos obligatorios para trabajar:
 Tlibversion  Versión de la librería
 Jspversion  Versión del jsp
 Shortname  El nombre del programador
 Tagclass  Nombre del paquete, nombre de la clase
 Bodycontent  Contenido del cuerpo, si no existe contenido, se pondrá Empty
Ejemplo de un archivo tld válido:
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>2.0<jspversion>
<shortname>Programeitor<shortname>
<tag>
<name>nombreetiqueta</name>
<tagclass>nombre del paquete y de la clase</tagclass>
<bodycontent>Es el contenido del cuerpo</bodycontent>
</tag>
</taglib>
Vamos a visualizar un ejemplo en el que crearemos una etiqueta personalizada que mostrará un
saludo.
Nos creamos un nuevo proyecto Java Web:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo llamaremos ProyectoCustomTags:

Utilizaremos el servidor Apache Tomcat que trae el IDE Netbeans.

Sobre la carpeta WEB-INF, nos crearemos una nueva carpeta que llamaremos FolderTLD. Para ello,
seleccionamos la opción Folder dentro de la categoría Other.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sobre la carpeta FolderTLD ya creada en nuestro proyecto, vamos a agregar un objeto Tag Library
Descriptor de la carpeta Web:

Lo llamaremos mensaje.

Escribiremos el siguiente código dentro del fichero mensaje.tld:


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>2.0</jspversion>
<shortname>mensaje</shortname>
<tag>
<name>primera</name>
<tagclass>paquetecustomtags.PrimeraEtiqueta</tagclass>
<bodycontent>empty</bodycontent>
</tag>
</taglib>
A continuación nos crearemos un nuevo paquete que contendrá la clase que dibujará nuestra
etiqueta, en nuestro ejemplo, hemos puesto lo siguiente:

Por lo que debemos crearnos una clase llamada PrimeraEtiqueta dentro de un paquete que se
llamará paquetecustomtags.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Implementamos el siguiente código dentro de la clase para, posteriormente, representarlo en una
página JSP:
package paquetecustomtags;

import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.TagSupport;
import java.util.*;
import java.text.*;

public class PrimeraEtiqueta extends TagSupport {

@Override
public int doStartTag() throws JspTagException
{
return SKIP_BODY;
}

@Override
public int doEndTag() throws JspTagException
{
String horaactual = this.GetHora();
try
{
JspWriter out = pageContext.getOut();
out.write("<h1>Bienvenido a mi pagina Custom Tags</h1>");

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
out.write("El nombre de mi clase es: ");
out.write(getClass().getName());
out.write("<br> y la hora es " + horaactual + "<p/>");
}catch (IOException ex)
{
throw new JspTagException("Excepcion al cargar el fichero TLD " +ex.toString());
}
return EVAL_PAGE;
}

private String GetHora()


{
Date horaactual;
DateFormat formato;
String cadhora;
horaactual= Calendar.getInstance().getTime();
formato= DateFormat.getTimeInstance();
cadhora=formato.format(horaactual);
return cadhora;
}
}
Ahora debemos irnos al descriptor de la aplicación web. Seleccionamos el fichero web.xml dentro de
la carpeta WEB-INF:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>mietiquetacustomtag</taglib-uri>
<taglib-location>/WEB-INF/FolderTLD/mensaje.tld</taglib-location>
</taglib>
</web-app>
La estructura de nuestra aplicación web quedaría de la siguiente forma:

Por último, escribiremos el siguiente código en la página index.jsp para realizar la llamada a la
librería Custom Tags que hemos creado:
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
"http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="mietiquetacustomtag" prefix="MiEtiqueta" %>
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Pagina realizada con Custom Tags</h1>
<MiEtiqueta:primera/>
</body>
</HTML>
Como podremos comprobar al ejecutar la aplicación, la llamada a nuestro Custom tag se realiza
correctamente siempre y cuando hayamos configurado correctamente todo.

Ver Video: Acciones con JavaBeans, en la Unidad 5, en el


Módulo 4, en la plataforma elearning

Laboratorio 1: Datos de Empleados


Objetivos
 Conocer el funcionamiento de las páginas JSP con acceso a datos.
 Implementar consultas dinámicas mediante código Java con código estático HTML.

Enunciado
Vamos a realizar una página JSP que contendrá un desplegable con todos los oficios de la tabla
empleados.
El desplegable lo cargaremos mediante código en la página JSP.
Posteriormente, cuando el usuario seleccione el oficio de un empleado, mostraremos los empleados
que tienen dicho oficio.
Lo primero que vamos a realizar será crearnos un nuevo proyecto Web Application.
Si ya hemos realizado prácticas anteriores, podemos saltarnos los pasos de creación de proyecto.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Le daremos el nombre de ProyectoJSP.

Utilizaremos el servidor Glassfish por defecto.

No implementaremos ningún Framework.

A continuación, nos crearemos una nueva página JSP.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Le daremos el nombre empleadosoficios

Lo que debemos realizar ahora es el acceso mediante JDBC a la tabla EMP de Oracle. Para ello,
debemos agregar dentro de la carpeta Libraries el conector JDBC para Oracle.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora implementaremos el código de la página JSP para mostrar en una lista los oficios y poder
recuperar los empleados.
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@page import="java.sql.*" %>
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>Empleados por oficio</title>
</head>
<body>
<%try {
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");
Statement sentencia =
cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
ResultSet rs = sentencia.executeQuery("SELECT DISTINCT JOB FROM EMP");%>
<H1>Oficios de Empleados</H1>
<FORM method='POST' action='empleadosoficios.jsp' name='form1'>
<SELECT NAME='cmboficio'>
<% String oficio="";
String opcioneshtml="";
oficio = request.getParameter("cmboficio");
while (rs.next())
{
String opcion = rs.getString(1);
if (opcion!=null && opcion.equals(oficio))
{
opcioneshtml += "<OPTION VALUE='"+opcion+"'
SELECTED>"+opcion+"</OPTION>";
}else{
opcioneshtml += "<OPTION VALUE='"+opcion+"'>"+opcion+"</OPTION>";
}
}%>
<%=opcioneshtml%>
</SELECT>
<INPUT TYPE='SUBMIT' VALUE='Ver empleados' NAME='btnbuscar'>
</FORM>

<%
String tabla="";
if (oficio!=null)
{
PreparedStatement pst = cn.prepareStatement("SELECT ENAME, JOB, DEPTNO FROM
EMP WHERE JOB=?");
pst.setString(1, oficio);
rs = pst.executeQuery();
tabla="<table border='1'>";
while (rs.next())
{
tabla += "<tr><td>"+rs.getString(1)+"</td></tr>";
tabla += "<tr><td>"+rs.getString(2)+"</td></tr>";
tabla += "<tr><td>"+rs.getString(3)+"</td></tr>";
}
tabla += "</table>";%>
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
<%=tabla%>
<%}%>
<%} catch (SQLException ex) {%>
<h1>Error: <%=ex.toString()%></h1>
<%}%>
</body>
</HTML>
Ya podremos ejecutar nuestro proyecto y comprobar el funcionamiento correcto de la aplicación:

Laboratorio 2: Custom Tags Departamentos


Objetivos
 Conocer el funcionamiento de la tecnología Custom Tags.
 Representar datos en páginas JSP a partir de etiquetas Custom Tags.

Enunciado
Vamos a realizar una página JSP que mostrará una tabla con los datos de los departamentos.
Para ello, utilizaremos la tecnología Custom Tags.
La página JSP solamente contendrá una etiqueta Custom Tag que será la encargada de dibujar la
tabla.
Lo primero que vamos a realizar será crearnos un nuevo proyecto Web Application.
Nos creamos un nuevo proyecto Java Web:

Lo llamaremos AplicacionCustomTags

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Utilizaremos el servidor Apache Tomcat que trae el IDE Netbeans.

No implementaremos ningún Framework.


Sobre la carpeta WEB-INF, nos crearemos una nueva carpeta que llamaremos EtiquetasDEPT. Para
ello, seleccionamos la opción Folder dentro de la categoría Other.

Sobre la carpeta EtiquetasDEPT ya creada en nuestro proyecto, vamos a agregar un objeto Tag
Library Descriptor de la carpeta Web:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo llamaremos etiquetadepartamentos

Escribiremos el siguiente código dentro del fichero etiquetadepartamentos.tld:

<?xml version="1.0" encoding="ISO-8859-1" ?>


<!DOCTYPE taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>2.0</jspversion>
<shortname>etiquetadepartamentos</shortname>
<tag>
<name>tabladepartamentos</name>
<tagclass>paquetecustomtags.EtiquetaTablaDept</tagclass>
<bodycontent>empty</bodycontent>
</tag>
</taglib>
A continuación nos crearemos una clase para poder implementar el código de la etiqueta que
acabamos de realizar.

Crearemos la clase en un paquete llamado paquetecustomtags y le pondremos de nombre


EtiquetaTablaDept.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo que debemos realizar ahora es el acceso mediante JDBC a la tabla EMP de Oracle. Para ello,
debemos agregar dentro de la carpeta Libraries el conector JDBC para Oracle.

A continuación, implementaremos el código de la clase EtiquetaTablaDept


package paquetecustomtags;
import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.TagSupport;
import java.util.*;

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
import java.text.*;
import java.sql.*;

public class EtiquetaTablaDept extends TagSupport {


@Override
public int doStartTag() throws JspTagException
{
return SKIP_BODY;
}

@Override
public int doEndTag() throws JspTagException
{
try
{
JspWriter out = pageContext.getOut();
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");
Statement sentencia = cn.createStatement();
//(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
ResultSet rs = sentencia.executeQuery("SELECT * FROM DEPT");
out.write("<h1>Datos de los departamentos</h1>");
String tabla = "<table border='1'>";
tabla += "<tr><th>Numero</th><th>Nombre</th><th>Localidad</th></tr>";
while (rs.next())
{
tabla += "<tr>";
tabla += "<td>"+rs.getString(1)+"</td>";
tabla += "<td>"+rs.getString(2)+"</td>";
tabla += "<td>"+rs.getString(3)+"</td>";
tabla += "</tr>";
}
tabla += "</table>";
out.write(tabla);
}catch (Exception ex)
{
throw new JspTagException("Excepcion al cargar el fichero TLD " +ex.toString());
}
return EVAL_PAGE;
}
}
Ahora debemos irnos al descriptor de la aplicación web.
Seleccionamos el fichero web.xml dentro de la carpeta WEB-INF y escribimos lo siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>mietiquetacustomtag</taglib-uri>
<taglib-location>/WEB-INF/EtiquetasDEPT/etiquetadepartamentos.tld</taglib-location>
</taglib>

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
</web-app>
Ahora vamos a agregar una pagina JSP que dibujará los empleados que tenemos en la etiqueta
Custom Tag.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Le daremos el nombre tabladepartamentos

Implementamos el código para dibujar los departamentos.


<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="mietiquetacustomtag" prefix="tagdept" %>
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<tagdept:tabladepartamentos/>
</body>
</HTML>
Ya podremos ejecutar nuestro proyecto y comprobar el funcionamiento correcto de la aplicación:

Laboratorio 3: Cargar Select dinámicamente con JavaBeans


Objetivos
 Conocer el funcionamiento de las clases JavaBeans dentro del entorno de aplicaciones JSP.
 Mantener el estado de los objetos HTML cargados dinámicamente desde acceso a datos.
Enunciado
Vamos a realizar una clase JavaBean que permita poder crear un desplegable a partir de objetos
ResultSet.
Dibujaremos un control HTML Select que mantendrá el elemento seleccionado cuando enviemos una
petición al servidor.
Lo primero de todo será crearnos un nuevo proyecto Web Application.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo llamaremos ProyectoJSPJavaBeans

Utilizaremos el servidor GlassFish Server.

No agregaremos ningún Framework.


Sobre las librerías vamos a agregar el conector para Oracle

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora vamos a agregar una clase Java que será la que dibujará los elementos en el Select y los
mantendrá seleccionados.

La llamaremos BeanDesplegable y crearemos un paquete llamado paquetebeans.

Implementamos el código del JavaBean para poder conectarnos, ejecutar consultas y un método
para dibujar objetos Select a partir de una consulta con dos datos.
package paquetebeans;
import java.sql.*;
public class BeanDesplegable {
Connection cn = null;
java.sql.Statement st = null;
final String usuario = "system";
final String password = "12345";
final String cadenaconexion = "jdbc:oracle:thin:@localhost:1521:XE";
public BeanDesplegable () {

}
public void conectar() throws SQLException, Exception
{
try
{
// 1.- Cargamos el driver
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
// 2.- Nos conectamos, paso el nombre de la conexion, usuario y contraseña.
this.cn = DriverManager.getConnection(cadenaconexion, usuario, password);
} catch (SQLException e)

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
{
System.out.println(e.toString());
}
}

public ResultSet crearResultSet(String consulta) throws Exception


{
ResultSet rs = null;
st = cn.createStatement();
rs = st.executeQuery(consulta);
return rs;
}

public String cargarCombo(ResultSet rs, String nombreselect, String valorseleccionado)


{
String combo;
try
{
combo = "<select name='"+nombreselect+"'>";
while (rs.next())
{
if (rs.getString(1).equals(valorseleccionado))
{
combo+="<option SELECTED ";
}else{
combo+="<option ";
}
combo+="value='"+rs.getString(1)+"'>";
combo+=rs.getString(2);
combo+="</option>";
}
combo += "</select>";
return combo;
} catch (SQLException ex) {
return ex.toString();
}
}
}
Ahora vamos a utilizar la página index.jsp del proyecto para poder realizar la llamada al Bean y
mostrar los datos de los departamentos. Lo interesante de la práctica es que mantendrá el
elemento seleccionado después de la llamada.
<%@page import="java.sql.ResultSet"%>
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<jsp:useBean id="practica" scope="session" class="paquetebeans.BeanDesplegable "/>
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>Cargar Desplegable</title>
</head>
<body>
<form name="form1" action="index.jsp" method="post">
Seleccione un departamento:
<%
practica.conectar();

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
ResultSet rs =practica.crearResultSet("SELECT DEPTNO,DNAME FROM DEPT");
String combo;
String etiqueta="";
if (request.getParameter("cmbdept")!=null)
{
String dept = request.getParameter("cmbdept");
combo = practica.cargarCombo(rs, "cmbdept", dept);
etiqueta = "<div>Elemento seleccionado:"+dept+"</div>";
}else{
combo = practica.cargarCombo(rs, "cmbdept", "");
}

%>
<%=combo%>
<input type="submit" value="Enviar formulario">
<%=etiqueta%>
</form>
</body>
</HTML>
Si ejecutamos la aplicación, comprobaremos el funcionamiento de la llamada.

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 6. Modelo de componentes EJB

Introducción
Enterprise Java Beans (EJB) es una plataforma para construir aplicaciones de negocio portables,
reutilizables y escalables usando el lenguaje de programación Java.
Desde el punto de vista del desarrollador, un EJB es una porción de código que se ejecuta en un
contenedor EJB, que no es más que un ambiente especializado (runtime) que provee determinados
componentes de servicio.
Los EJBs pueden ser vistos como componentes, desde el punto de vista que encapsulan
comportamiento y permite reutilizar porciones de código, pero también pueden ser vistos como un
framework, ya que, desplegados en un contenedor, proveen servicios para el desarrollo de
aplicaciones empresariales, servicios que son invisibles para el programador y no ensucian la lógica
de negocio con funcionalidades trasversales al modelo de dominio.
En la especificación 3.0, los EJB no son más que POJOs (clases planas comunes y corrientes de
Java) con algunos poderes especiales implícitos, que se activan en tiempo de ejecución (runtime)
cuando son ejecutados en un contenedor de EJBs.
Objetivos
 Conocer los tipos de EJBs que existen dentro de la versión 3.0.
 Entender la tecnología de los EJB y conocer su funcionalidad y características.

Componentes EJB
Con la tecnología Enterprise JavaBeans es posible desarrollar componentes (enterprise beans) que
luego podemos reutilizar y ensamblar en distintas aplicaciones que implementemos en la empresa.
Por ejemplo, podríamos desarrollar un bean Cliente que represente un cliente en una base de datos.
Dicho vean Cliente podríamos usarlo, posteriormente, en un programa de agenda o en una
aplicación de comercio electrónico o virtualmente en cualquier programa en el que se necesite
representar un cliente.
Con esta tecnología, podemos separar las capas, llegando incluso a ser posible que el desarrollador
del bean y el ensamblador de la aplicación no fueran la misma persona, o ni siquiera trabajaran en
la misma empresa.
El desarrollo basado en componentes promete un paso más en el camino de la programación
orientada a objetos.
Con la programación orientada a objetos podemos reutilizar clases, pero con componentes es
posible reutilizar un mayor nivel de funcionalidades e incluso es posible modificar estas
funcionalidades y adaptarlas a cada entorno de trabajo particular sin tocar el código del componente
desarrollado.
El contenedor de componentes se denomina contenedor EJB y es algo así como el sistema operativo
en el que éstos residen.
Cuando se utilizan componentes en un marco de trabajo, debemos prestar atención tanto al
desarrollo de los beans como a los descriptores de despliegue que comunican nuestro trabajo con el
contenedor.
Debemos recordar que un descriptor de despliegue ofrece la información del componente a nuestro
contenedor EJB y a nuestro entorno de trabajo (bases de datos, arquitectura de la aplicación, etc.).
El despliegue se define de forma declarativa, mediante un fichero XML (descriptor del despliegue,
deployment descriptor) en el que se definen todas las características del bean o con anotaciones.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El funcionamiento de los componentes EJB se basa fundamentalmente en el trabajo del contenedor
EJB.
El contenedor EJB es un programa Java que trabaja en el servidor y que contiene todas las clases y
objetos necesarios para el correcto funcionamiento de los EJBs.
Los servicios que ofrece un contenedor de EJBs son los siguientes:
 Integración: Proveen una forma de acoplar en tiempo de ejecución diferentes componentes,
mediante la simple configuración de anotaciones xml. La integración es un servicio que
proveen los beans de sesión y los MDBs.
 Pooling: El contenedor de EJBs crea para componentes EJB un pool de instancias que es
compartido por los diferentes clientes. Aunque cada cliente visualiza el entorno como si
recibiera siempre instancias diferentes de los EJB, el contenedor está constantemente
reutilizando objetos para optimizar memoria. El pooling es un servicio que se aplica a los
Stateless Session Beans y a los MDBs.
 Thread-safely: El programador puede escribir componentes del lado del servidor como si
estuviera trabajando en una aplicación sencilla con un solo thread (hilo). El contenedor se
encarga de que los EJBs tengan el soporte adecuado para una aplicación multi-usuario (como
son en general las aplicaciones empresariales) de forma transparente, asegurando el acceso
seguro, consistente y alto rendimiento. Se aplican a los beans de sesión y a los MDBs.
 Administración de Estados: El contenedor de EJBs almacena y maneja el estado de un
Stateful Session Bean de forma transparente, lo que significa que el programador puede
mantener el estado de los miembros de una clase como si estuviera desarrollando una
aplicación de escritorio ordinaria. El contenedor manipula los detalles de las sesiones.
 Mensajería: Mediante los MDBs es posible desacoplar por completo dos componentes para
que se comuniquen de forma asincrónica, sin reparar demasiado en los mecanismos de la
JMS API que los MDBs encapsulan.
 Transacciones: EJB soporta el manejo de transacciones declarativas que permiten agregar
comportamiento transaccional a un componente simplemente usando anotaciones xml de
configuración. Esto significa que cuando un método de un EJB (Session Bean o MDB) se
completa normalmente, el contenedor se encargará de finalizar la transacción y validar los
cambios que se realizaron en los datos de forma permanente. Si algo fallara durante la
ejecución del método (una excepción o cualquier otro problema), la transacción haría un
rollback y es como si el método jamás se hubiera invocado.
 Seguridad: EJB soporta integración con la Java Authentication and Authorization Service
(JAAS) API, haciendo casi transparente el manejo transversal de la seguridad. Se aplica a
todos los Session Beans.
 Interceptors: EJB introduce un framework liviano y simple para AOP (programación
orientada a aspectos). No es tan robusto y completo como otros, pero es lo suficientemente
útil para que sea utilizado por los demás servicios del contenedor para brindarnos de forma
invisible los crosscutting concerns de seguridad, transacciones, thread-safely.
 Acceso Remoto: Es posible acceder de forma remota a distintos EJBs de forma sencilla,
simplemente mediante la Inyección de Dependencia. El procedimiento para inyectar un
componente local o uno remoto es exactamente el mismo, abstrayéndonos de las
complicaciones específicas de RMI o similares. Este servicio aplica únicamente a los Session
Beans.
 Web Services: Un Stateless Session Bean puede publicar sus métodos como servicios web
mediante una sencilla anotación.
 Persistencia: EJB 3 provee la especificación JPA para el mapeo de objetos llamados
Entidades a tablas o POJOs.
Aquí tenemos un gráfico que mostraría la representación de EJB dentro de un módulo web.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Tipos de beans
Existen tres tipos de beans definidos, cada uno implementa unas características diferentes y
permiten ser combinados entre si.
Beans de Sesión (Session Beans)
En una aplicación típica, dividida en grandes capas (presentación, lógica de negocio, persistencia y
base de datos), los Beans de Sesión viven en la lógica de negocio.
Hay dos grandes tipos de Beans de Sesión:
 Stateless (sin estado)
 Stateful (con estado)
Stateless no conserva el estado de ninguno de sus atributos de la invocación de un método a otro.
Stateful conserva el estado a lo largo de toda una sesión. Los Beans de Sesión Stateless son los
únicos que pueden exponerse como servicios web.
Los beans de sesión son invocados por el cliente con el propósito de ejecutar operaciones de negocio
específicas, como por ejemplo podría ser mostrar todos los datos de una determinada tabla.
El nombre sesión implica que la instancia del bean estará disponible durante una unidad de trabajo
(unit of work) y no sobrevivirá a una caída del servidor.
Un bean de sesión sirve para modelar cualquier funcionalidad lógica de una aplicación y se utilizan
para realizar acciones y representar propiedades de objetos.
Message-Driven Beans (MDBs)
Viven en la lógica de negocio y los servicios que proveen son parecidos a los Beans de Sesión, con la
diferencia de que los MDBs son usados para invocar métodos de forma asincrónica.
Cuando se produce la invocación de un método de un MDB desde un cliente, la llamada no bloquea
el código del cliente y el mismo puede seguir con su ejecución, sin tener que esperar
indefinidamente por la respuesta del servidor.
Los MDBs encapsulan el popular servicio de mensajería de Java, Java Message Service (JMS).
Los MDBs también procesan lógica de negocio, pero un cliente nunca invoca a un método de un MDB
directamente.
El sistema de mensajería asincrónica propone la utilización de una capa intermedia en la
comunicación entre el creador y el consumidor del mensaje.
En EJB 3, esta capa se llama MOM (Message-oriented Middleware). Básicamente, MOM es un
software que permite funcionar como servidor de mensajería, reteniendo los mensajes del
productor y enviándolos posteriormente al consumidor en el momento en que esté disponible para
recibirlo.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Beans de Entidad (Entities)
Las entidades viven en la capa de persistencia y son los EJBs que manejan Java Persistence API
(JPA), también parte de la especificación de EJB 3.0.
Las entidades son POJOs con cierta información metadata que permite a la capa de persistencia
mapear los atributos de la clase a las tablas de la base de datos y sus relaciones.
Existen dos tipos BMP y CMP según se gestione la persistencia por parte del bean o del contenedor.
Los EJB de entidad están directamente relacionados con los datos de la aplicación, son objetos que
mantienen en memoria los datos que maneja la aplicación, las entidades que disponen de
persistencia.
Los Beans de Entidad normalmente mapean (mantienen una relación en memoria) las tablas de
una base de datos relacional, aunque también es posible que mantengan la persistencia de los datos
en ficheros, como por ejemplo un xml.
En cualquiera de los casos el objetivo de un Bean de Entidad es almacenar los datos en memoria
desde una fuente persistente y mantener una sincronización total entre el estado de los datos entre
la memoria y la fuente de datos.
Por esta razón se dice que los Beans de Entidad son los EJB que sobreviven a caídas del sistema, ya
que en caso de un fallo del sistema, los datos que hay en memoria estarían guardados en el
dispositivo persistente, como por ejemplo la base de datos, con lo cual, cuando se reinicie el
servidor se recuperarán sin ningún problema.

Anotaciones de un bean
Para poder configurar correctamente un vean, debemos indicar al contenedor de EJB qué servicios
debe proveer a nuestro Bean, y para ello disponemos de los descriptores de despliegue o de las
anotaciones en las clases bean.
Vamos a visualizar las anotaciones básicas para los Session Beans.

@Stateful
Indica que el Bean de Sesión es con estado. Sus atributos son:
 name: por defecto es el nombre de la clase pero se puede especificar otro nombre diferente.
 mappedName: Indica si deseamos que el contenedor maneje el objeto de forma específica.
Si incluimos esta opción nuestra aplicación podría no ser portable y no funcione en otro
servidor de aplicaciones.
 description: Indica la descripción de la anotación.

@Stateless
Indica que el Bean de Sesión es sin estado. Sus atributos son:
 name: Por defecto el nombre de la clase pero se puede especificar otra diferente.
 mappedName: Si deseamos que el contenedor maneje el objeto de manera específica. Al
igual que @StateFul esta opción podría hacer que nuestra aplicación no sea portable y no
funcione en otro servidor de aplicaciones.
 Description: descripción de la anotación.

@Init
Especifica que el método se corresponde con un método create de un EJBHome o EJBLocalHome de
EJB 2.1.
Sólo se podrá llamar una única vez a este método. Sus atributos son:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 Value: indica el nombre del correspondiente método create de la interfaz home adaptada.
Sólo se debe utilizar cuando se utiliza el bean anotado con un bean con estado de la
especificación 2.1 o anterior y que disponga de más de un método create.

@Remove
Indica que el contenedor debe llamar al método cuando quiera destruir la instancia del Bean. Sus
atributos son:
 retainIfException: indica si el Bean debe mantenerse activo si se produce una excepción. Por
defecto su valor es false.

@Local
Indica que la interfaz es local.

@Remote
Indica que la interfaz es remota.

@PostActivate
Invocado después de que el Bean sea activado por el contenedor.

@PrePassivate
Invocado antes de que el Bean esté en estado passivate.
Normalmente las anotaciones más empleadas en las aplicaciones serán @Stateless y @Stateful,
para indicar el tipo de EJB que estemos utilizando. El resto de anotaciones se utilizarán en casos
más particulares.

Role de EJB dentro de las aplicaciones JEE


La especificación Enterprise JavaBeans está escrita para diferentes públicos, pero podría resumirse
en dos niveles diferentes:

El desarrollador del cliente


Un cliente es cualquier usuario de un Enterprise JavaBean y podría ser cualquier aplicación Java del
lado del cliente, un servlet o incluso otro EJB.
Un programador del lado del cliente que diseña una aplicación Web o utilice un servlet para
establecer la comunicación con un EJB, necesita comprender como se accede a los EJB y como se
utilizan.
En proyectos de grandes dimensiones, es bastante probable que el programador Web y el
programador EJB sean personas distintas.
El programador cliente tiene menos preocupaciones que un desarrollador bean en cuanto al uso de
EJB.
Necesitan saber como encontrar o crear un bean, como utilizar sus métodos y cómo liberar sus
recursos.
Un cliente siempre utiliza el mismo procedimiento para la creación de objetos, búsquedas e
invocación de métodos, independientemente de como se implemente un EJB determinado.
El cliente no necesita preocuparse sobre la implementación del EJB, solamente debe tener en cuenta
las acciones o propiedades del bean para representar los elementos en las páginas.

El desarrollador EJB
La principal responsabilidad del programador de un bean será escribir la lógica de empresa y
acciones o propiedades.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Siempre que sea posible, la especificación Enterprise JavaBeans intenta abstraer a los
programadores de un bean de cualquier tarea de nivel de sistema.
El programador de un bean debe estructurar su código de una forma determinada.
No importa el tipo de EJB que se esté desarrollando, normalmente deben crearse archivos de clase
primarios y un descriptor xml o bien, incluir anotaciones en las clases del bean.
También podríamos tener clases Java adicionales que apoyen la operación del bean, clases de ayuda
que implementen la lógica de negocio.
Todos estos archivos estarían empaquetados en un JAR, ya hemos visto que es la unidad estándar
de empaquetado de clases de Java.
Podríamos tener muchos beans dentro de un único archivo JAR, pero cada archivo JAR contendría
únicamente descriptor del bean xml.
El descriptor de implementación debe situarse en un directorio especifico, de forma que el
contenedor EJB sabría donde buscarlo.

Este directorio se llama META- INF y no podemos cambiarle el nombre, sigue una especificación
estándar.
Aquí podemos visualizar la implementación del uso de un EJB dentro de un entorno de desarrollo,
independientemente que sea realizada la llamada desde un navegador o desde una aplicación Java.

Estructura de EJB
Todo EJB está compuesto por dos capas.
 Capa Interfaz

La capa Interfaz es un contrato que indica a las clases que consuman el EJB los métodos y
características de dicho EJB.
Para poder trabajar con EJB, necesitamos tener una Interfaz que contenga los métodos que vamos a
exponer a un cliente final.
 Capa Implementación

La capa de implementación es una clase que implementa la capa de Interfaz.


Una clase que hereda directamente de la interfaz del EJB e implementa los métodos que se hayan
incluido en el contrato.
Por último, el cliente que consuma nuestro EJB, sabrá los métodos que contiene debido al contrato
de nuestra interfaz. Nuestro código estará fuertemente tipado debido a que la clase EJB debe
implementar todos los métodos de la interfaz y el cliente tendrá la seguridad que esos métodos no
van a variar el “contrato”.
Vamos a visualizar una creación y una llamada a un EJB:
Lo vamos a hacer creándonos un nuevo proyecto de Java  Aplicación Java.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sobre nuestro nuevo proyecto y sobre el paquete creado, vamos a agregar una Interfaz que será el
contrato.

Llamaremos a nuestra Interfaz: InterfazEJB

Simplemente vamos a escribir un código con un método que recibirá un tipo de dato String.
Escribimos el siguiente código en la Interfaz.
package javaapplication1;
public interface InterfazEJB {
public void GetMensaje(String nombre);
}
A continuación, nos crearemos una clase sobre el mismo paquete que llamaremos ClaseEJB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Dicha clase se encargará de implementar la Interfaz de contrato EJB. Para poder trabajar con ello,
debemos utilizar el espacio de nombres siguiente:
import javax.ejb.Stateless
Como podemos comprobar en la imagen, no reconoce la librería de los EJB, por lo que tendremos
que incluirla manualmente para poder trabajar con dichas clases.

En la carpeta Biblioteca de NetBeans, irán todas las librerías relacionadas con nuestro proyecto.
Lo que vamos a realizar es agregar la librería que permite trabajar con EJB. Para ello,
seleccionamos en el menú contextual: “Agregar archivo JAR/carpeta”.

Buscamos la librería de ejb en la carpeta dónde la hayamos situado. Dicha librería es proporcionada
en la documentación del módulo.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Una vez que ya tenemos la librería añadida, ahora es el momento de implementar la Interfaz sobre
la ClaseEJB. Para ello escribimos el siguiente código:
public class ClaseEJB implements InterfazEJB {
Como vemos en la imagen, nos dará un fallo debido a que tenemos que implementar todos los
métodos que contenga la Interfaz de la que estamos heredando.

Para implementar los métodos, NetBeans ofrece una herramienta muy útil que “lee” todos los
métodos de la Interfaz y los implementa dentro de nuestra clase.
Si pulsamos sobre el símbolo de la bombilla de la izquierda del código, nos aparecerá una opción
para Implementar los métodos. Seleccionamos dicha opción.

Una vez que tenemos todos los métodos implementados, escribimos el siguiente código dentro de la
clase llamada ClaseEJB.
package javaapplication1;
import javax.ejb.Stateless;
public class ClaseEJB implements InterfazEJB
{
public void GetMensaje(String nombre) {
System.out.println("Primer EJB, Bienvenido a la tecnología " + nombre);
}
}
Ahora nos quedará crearnos un cliente que consuma nuestro bean.
Para ello, debemos agregar una nueva clase sobre el paquete creado y la llamaremos ClienteEJB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sobre dicho cliente escribiremos la implementación del consumo del Bean. Para indicar que estamos
utilizando un contrato, utilizaremos la anotación @EJB para que el contenedor reconozca nuestra
lógica de negocio.
Escribimos el siguiente código dentro de la clase ClienteEJB:
package javaapplication1;
import javax.ejb.EJB;
public class ClienteEJB {
@EJB
private ClaseEJB BeanEJB;
void MetodoCliente()
{
BeanEJB = new ClaseEJB();
BeanEJB.GetMensaje("Usuario de EJB");
}
}
Por último, nos quedará mostrar el resultado de la aplicación. Para ello, iremos a la clase inicial de
los proyectos de J2SE llamada Main.java.
En el código de arranque de la clase, crearemos el objeto cliente, que a su vez, llamará al método
del Bean que seguirá el contrato de la Interfaz.
Implementamos el siguiente código en Main.java:
package javaapplication1;
public class Main {
public static void main(String[] args) {
ClienteEJB cliente = new ClienteEJB();
cliente.MetodoCliente();
}
}

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Como podemos comprobar cuando ejecutemos la aplicación (tecla F6), veremos el resultado de la
llamada al Bean en la consola de NetBeans.

Ver Video: Llamada a un Bean desde una aplicación J2EE, en


la Unidad 6, en el Módulo 4, en la plataforma elearning

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 7. Implementación de las sesiones
EJB 3.0

Introducción
Un bean de sesión representa a un cliente dentro de un servidor J2EE.
Para acceder a una aplicación desplegada en el servidor, el cliente invoca métodos del bean de
sesión.
Es el bean de sesión quien ejecuta el trabajo para su cliente protegiéndolo de la complejidad de la
lógica del negocio.
Un bean de sesión no es compartido ni persistente.
Es hospedado en un contenedor EJB.
Sus características más importantes son:
 Llevan a cabo las reglas de negocio para un cliente.
 No son persistentes.
 Cuando su cliente termina, el bean no está más asociado con el cliente, aunque sigue
existiendo.
 Implementan Web Services.
Objetivos
 Comprender los diferentes tipos de anotaciones en los Beans de session.
 Conocer la funcionalidad y características de la tecnología EJB con Beans de session.

Tipos de Beans Session


Existen dos tipos de Bean de Session:
Stateful

El estado de un objeto consiste en el valor de sus variables de instancia.


En un bean de sesión con estado, las variables de instancia representan el estado de una única
sesión de cliente-bean.
Permanece hasta el fin de la sesión.
Características más importantes:
 Mantienen estado de sesión.
 Cada cliente usa una instancia del bean.
 Se especifican mediante la anotación @Stateful.
Stateless

Una sesión stateless no mantiene un estado conversacional para un cliente en particular.


Cuando un cliente invoca uno de sus métodos, las variables de instancia del bean pueden contener
estados, pero sólo durante la invocación.
Puede servir a muchos clientes.
Características más importantes:
 No mantienen el estado del cliente.
 El contenedor crea pools de Session bean stateless usados por n clientes.
 Se especifican mediante la anotación @Stateless

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Debemos tener en cuenta ciertas consideraciones en el momento de utilizar una clase de bean de
session:
Deberíamos considerar utilizar los beans de sesión cuando se cumplan algunas de las siguientes
condiciones:
 En cualquier momento, un sólo cliente accede al bean.
 El estado del bean no es persistente.

Debemos utilizar un bean @Stateful cuando ocurra alguna de estas condiciones:


 El estado del bean representa la interacción entre éste y un cliente.
 El bean requiere mantener información del cliente entre invocaciones de métodos.
 El bean es mediador entre el cliente y otros componentes de la aplicación.

Debemos utilizar un bean @Stateless cuando ocurra alguna de estas condiciones:


 El bean no mantiene información para un cliente específico.
 En una invocación a un método, el bean ejecuta tareas genéricas para todos los clientes.
 El bean extrae de una base de datos un conjunto de información de sólo-lectura.

Ciclo de vida de los beans de Session


El ciclo de vida de los beans de sesión depende del tipo de anotación en la que se ha delimitado
dicho Bean:
Ciclo de vida Bean @StateFul:
 Creación: Cuando el cliente ejecuta el método create().
 Uso: Cuando el cliente llama un método de negocio.
 Desactivación: El bean se manda a memoria secundaria.
 Activación: El bean es despertado para servir algún método al cliente.
 Destrucción: Cuando el cliente termina su sesión con el bean.

1) El cliente crea una instancia del session bean cuando obtiene una referencia usando la
interfaz remota o local.
2) El contenedor ejecuta lo indicado por las anotaciones del bean (dependency injections) y a
continuación invoca al método anotado con @PostConstruct (si lo hay).
3) El session bean queda en estado ready para que sus métodos sean invocados por el cliente.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
4) El bean puede ser desactivado (passivated) si el contenedor lo decide. Antes de la
desactivación se invocan los métodos anotados con @PrePassivate.
5) Si el cliente invoca un método cuando el bean está en estado passivated, el contenedor lo
activa y ejecuta el método anotado con @PostActivate y lo pasa al estado ready nuevamente.
6) El cliente puede invocar un método anotado con @Remove en cuyo caso el contenedor
invoca antes el método anotado con @PreDestroy.

Ciclo de vida Bean @Stateless:


 Creación: Cuando el contenedor quiere un bean.
 Uso: Cuando el cliente llama un método de negocio.
 Destrucción: Cuando el contenedor decide que hay muchos beans en el pool.

1) Se crea una instancia del session bean cuando algún cliente obtiene una referencia usando la
interfaz local o remota.
2) El contenedor ejecuta lo indicado por las anotaciones del bean (dependency injections) y a
continuación del bean (dependency injections) y a continuación invoca al método anotado
con @PostConstruct (si lo hay).
3) El session bean queda en estado ready para que sus métodos sean invocados por el cliente.
4) No existe el estado passivated.
5) Si un cliente invoca un método anotado con @Remove el contenedor invoca antes el método
anotado con @PreDestroy.
6) La instancia del bean permanece en un pool.
Métodos de los beans de session
Como hemos visto, todos los beans de session pueden compartir una serie de métodos en común
para el ciclo de vida.
Los métodos se marcan con anotaciones y especifican todo el comportamiento a lo largo del ciclo de
vida del propio bean.
Algunos métodos en la clase del Bean se pueden marcar con las siguientes anotaciones:
 javax.annotation.PostConstruct.
 javax.annotation.PreDestroy.
 javax.ejb.PostActivate.
 javax.ejb.PrePassivate.
Estos métodos son invocados automáticamente por el EJB container.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
No tienen parámetros y son tipos de métodos void.
Los métodos anotados con @PostConstruct son invocados cuando se instancia un bean, después de
la inyección de las anotaciones y antes de que se invoque el primer método de negocio.
Los métodos anotados con @PreDestroy son invocados después de la ejecución de métodos
anotados con @Remove y antes de que el contenedor elimine la instancia del bean.
Los métodos anotados con @PostActivate son invocados después de que el contenedor mueva el
bean de memoria secundaria a estado activo.
Los métodos anotados con @PrePassivate son invocados antes de que el contenedor elimine el bean
del ambiente activo y lo salve en la memoria secundaria.
Un método anotado con @Remove es un método de ciclo de vida especial, que puede ser invocado
por el cliente del bean.
Después de su ejecución el contenedor llama al método anotado con @PreDestroy, si existe.
A continuación la instancia queda sin referencia y lista para ser procesada con el Garbage Collector.

Clientes del Bean


Un cliente sólo puede acceder un Session Bean a través de los métodos definidos en la Interfaz.
El cliente accede al bean mediante los métodos definidos en las interfaces.
Pueden tener dos tipos de interfaces
 Remotas.
 Locales.
El tipo de cliente determina que interfaces se usan.
Un cliente remoto de un session bean:
 Corre en una máquina virtual de Java diferente a la del bean.
 Puede ser un programa standalone, un componente web (servlet o JSP) u otro EJB.
 La localización del bean es transparente para el cliente.
 Para definirlo debe usarse la anotación @Remote y puede hacerse de dos formas diferentes.
Para crear un session bean que soporte un cliente remoto:
 Podemos especificar la interfaz remota con la anotación de java @Remote:
@Remote
public interface MiBeanRemoto
{
//CODIGO DEL BEAN
}
 Podemos especificar la clase principal con la anotación @Remote con la interfaz como
parámetro:
@Remote(MiBeanRemote.class)
public class MiBean implements MiBeanRemote
{
//CODIGO DE LA CLASE
}

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Un cliente local de un session bean:
 Debe correr en la misma máquina virtual de Java que el bean.
 Normalmente es otro EJB.
 La localización del bean NO es transparente para el cliente.
 Para definirlo debe usarse la anotación @Local en la declaración de la interfaz o nada, que es
por defecto.

Para crear un session bean que soporte un cliente local:


 Debemos especificar la interfaz remota con la anotación de java @Local:
@Local
public interface MiBeanLocal
{
//CODIGO DEL BEAN
}
 Debemos especificar la clase principal con la anotación @Local con la interfaz como
parámetro:
@Local(MiBeanLocal.class)
public class MiBean implements MiBeanLocal
{
//CODIGO DE LA CLASE
}
Factores a considerar para utilizar acceso local o acceso remoto:
 Beans relacionados entre sí deben usar interfaces locales para comunicarse entre ellos.
 Clientes en otras máquinas virtuales en el Application Server deben usar interfaces remotas.
 Clientes en máquinas reales diferentes deben usar interfaces remotas.
 Las interfaces locales siempre tienen mejor rendimiento.
 Los parámetros de los métodos remotos deben ser objetos con atributos en lugar de
primitivos.
 En las interfaces locales el cliente y el EJB pueden modificar el valor de un parámetro.

Vamos a crearnos un bean de prueba con una nueva aplicación Java Enterprise. Debemos hacer
que el bean sea remoto debido a que estará ubicado en otro “proyecto”, que es el proyecto EJB de la
aplicación.

Lo llamaremos ProyectoBeanSession

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Crearemos el proyecto marcando la opción para generar los proyectos de tipo WAR y EJB y
utilizaremos el servidor GlassFish Server versión 3.

A continuación, sobre el proyecto EJB, crearemos un nuevo Session Bean.

Dejaremos el nombre por defecto NewSessionBean y lo incluiremos en un paquete cualquiera, por


ejemplo paquetebean.

Marcaremos la opción de tipo Session Stateful e indicaremos que será de tipo remoto y
seleccionaremos el nombre del proyecto EJB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Una vez creado el Bean, vamos a implementar un método de acción que llamaremos
posteriormente.
Para ello, debemos ir al proyecto EJB, sobre la carpeta Enterprise Bean, seleccionamos la opción Add
 Bussines Method para crearnos un método de negocio que llamaremos posteriormente.

Escribimos el nombre del método, en nuestro caso getSaludo, e indicamos que el tipo que devolverá
es de la clase String.

Nos generará un código con el método de negocio getSaludo y que lo implementaremos de la


siguiente forma:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
package paquetebean;
import javax.ejb.Stateless;
@Stateless
public class NewSessionBean implements NewSessionBeanRemote {
@Override
public String getSaludo() {
return "Mensaje enviado desde un EJB @Stateless";
}
}
Ahora vamos a agregar un Servlet que implementará la funcionalidad del componente EJB que nos
hemos creado.
Sobre el proyecto WAR, seleccionaremos la opción New  Servlet.

Lo llamaremos ServletLlamadaEJB y lo incluiremos en un paquete cualquiera, en nuestro ejemplo lo


hemos llamada paqueteservlets.

No incluiremos la información en el archivo descriptor de la aplicación, aunque si lo hiciéramos, la


llamada al EJB seguiría siendo la misma.

Una vez que nos ha creado el servlet, debemos implementar la llamada, para ello utilizaremos el
asistente de código que nos permite insertar código generado dinámicamente.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sobre el código del servlet, seleccionamos la opción Insert Code

Nos aparecerán una serie de opciones, nosotros seleccionaremos la opción que llama a un Bean.
Marcaremos la opción Call Enterprise Bean.

Al seleccionar dicha opción, nos muestra una ventana dónde debemos indicar el Bean que vamos a
llamar desde el servlet. Buscamos el bean en el proyecto EJB y pulsamos sobre OK.

Podremos comprobar en el código que nos genera las librerías necesarias para realizar la llamada al
Bean de Session.
import javax.ejb.EJB;
import paquetebean.NewSessionBeanRemote;

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
También nos generará un objeto para poder invocar al método getSaludo desde nuestro servlet.
Dicho objeto podremos comprobar que contiene la anotación @EJB.
@EJB
private NewSessionBeanRemote newSessionBean;
Una vez que tenemos todo montado, podremos comprobar en cualquier método de la clase (por
ejemplo processRequest) que la llamada nos muestra el método getSaludo() del objeto Bean.

Ahora vamos a implementar el servlet para poder escribir el saludo escrito y enviado desde el EJB:
package paqueteservlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ejb.EJB;
import paquetebean.NewSessionBeanRemote;

@WebServlet(name="ServletLlamadaEJB", urlPatterns={"/ServletLlamadaEJB"})
public class ServletLlamadaEJB extends HttpServlet {
@EJB
private NewSessionBeanRemote newSessionBean;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet ServletLlamadaEJB</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet con llamada a EJB</h1>");
out.println(newSessionBean.getSaludo());
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();
}
}
@Override

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Solamente nos quedaría realizar la llamada al Servlet. Para ello, sobre el proyecto WAR vamos a
seleccionar la página que trae por defecto index.jsp y la implementaremos.

Escribiremos el siguiente código para poder llamar al servlet.


<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Bienvenido a la prueba de EJB</h1>
<form name="form1" action="ServletLlamadaEJB">
<input type="submit" value="Pulse para llamar al componente EJB">
</form>
</body>
</HTML>
Debemos recordar que las aplicaciones empresariales son un conjunto de elementos y contenedores
de los objetos, por lo que debemos ejecutarla en su conjunto con la tecla F6.
Cuando ejecutemos nuestra aplicación, veremos la página inicial index.jsp con el diseño que
hayamos realizado.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Una vez que pulsemos sobre el botón, comprobaremos que el mensaje desde el EJB llega
correctamente.

Ver Video: Creación de un bean con acceso a datos, en la


Unidad 7, en el Módulo 4, en la plataforma elearning

Laboratorio: Buscador Empleado


Objetivos
 Conocer el de la tecnología EJB.
 Acceso a datos en Beans de estado.
Enunciado
Vamos a realizar una aplicación que buscará un empleado y devolverá sus datos utilizando para la
lógica un Bean de session.
Para ello, utilizaremos la tecnología EJB y un proyecto empresarial.
Lo primero que vamos a realizar será crearnos un nuevo proyecto Enterprise Application.
Debemos hacer que el bean sea remoto debido a que estará ubicado en otro “proyecto”, que es el
proyecto EJB de la aplicación.

Lo llamaremos ProyectoEJBEmpleados

Crearemos el proyecto marcando la opción para generar los proyectos de tipo WAR y EJB y
utilizaremos el servidor GlassFish Server versión 3.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo primero que vamos a realizar será traernos las librerías para trabajar con datos. Para ello, sobre
el proyecto EJB, agregaremos la librería de Oracle.

A continuación, sobre el proyecto EJB, crearemos un nuevo Session Bean.

Lo llamaremos BeanBuscadorEmpleados y lo incluiremos en un paquete cualquiera, por ejemplo


paquetebean.

Marcaremos la opción de tipo Session Stateful e indicaremos que será de tipo remoto y
seleccionaremos el nombre del proyecto EJB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Una vez creado el Bean, vamos a implementar un método de acción que llamaremos
posteriormente.
Para ello, debemos ir al proyecto EJB, sobre la carpeta Enterprise Bean, seleccionamos la opción Add
 Bussines Method para crearnos un método de negocio que llamaremos posteriormente.

Escribimos el nombre del método, en nuestro caso buscarEmpleado, e indicamos que el tipo que
devolverá es de la clase String.

También le indicaremos que el método recibirá un dato de tipo int al que llamaremos idempleado.

Nos generará un código con el método de negocio buscarEmpleado y lo implementaremos para


buscar un empleado en nuestra tabla EMP:
package paquetebean;
import javax.ejb.Stateless;
import java.sql.*;
@Stateless
public class BeanBuscadorEmpleados implements BeanBuscadorEmpleadosRemote {

@Override
public String buscarEmpleado(int idempleado) {
try
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");
Statement sentencia = cn.createStatement();
ResultSet rs = sentencia.executeQuery("SELECT ENAME, JOB, SAL FROM EMP");
String dato = "";
if (rs.next())
{
dato = "<table border='1'>";
dato += "<tr>";
dato += "<td>"+rs.getString(1)+"</td>";
dato += "<td>"+rs.getString(2)+"</td>";
dato += "<td>"+rs.getString(3)+"</td>";
dato += "</tr>";
dato += "</table>";
}else
{
dato = "<h1>No existe el empleado buscado</h1>";
}
return dato;
}catch (Exception ex)
{
return ex.toString();
}
}
}
Ahora vamos a agregar un Servlet que implementará la funcionalidad del componente EJB que nos
hemos creado.
Sobre el proyecto WAR, seleccionaremos la opción New  Servlet.

Lo llamaremos ServletEmpleado y lo incluiremos en un paquete cualquiera, en nuestro ejemplo lo


hemos llamada paqueteservlets.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
No incluiremos la información en el archivo descriptor de la aplicación, aunque si lo hiciéramos, la
llamada al EJB seguiría siendo la misma.

Una vez que nos ha creado el servlet, debemos implementar la llamada, para ello utilizaremos el
asistente de código que nos permite insertar código generado dinámicamente.
Sobre el código del servlet, seleccionamos la opción Insert Code

Nos aparecerán una serie de opciones, nosotros seleccionaremos la opción que llama a un Bean.
Marcaremos la opción Call Enterprise Bean.

Al seleccionar dicha opción, nos muestra una ventana dónde debemos indicar el Bean que vamos a
llamar desde el servlet. Buscamos el bean en el proyecto EJB y pulsamos sobre OK.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Podremos comprobar en el código que nos genera las librerías necesarias para realizar la llamada al
Bean de Session.
Ahora vamos a implementar el servlet para poder escribir el saludo escrito y enviado desde el EJB:
package paqueteservlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import paquetebean.BeanBuscadorEmpleadosRemote;

@WebServlet(name="ServletEmpleado", urlPatterns={"/ServletEmpleado"})
public class ServletEmpleado extends HttpServlet {
@EJB
private BeanBuscadorEmpleadosRemote beanBuscadorEmpleados;

protected void processRequest(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet ServletEmpleado</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Llamada EJB empleados</h1>");
String respuesta;
int idempleado;
String numeroempleado = request.getParameter("txtnumero");
idempleado = Integer.parseInt(numeroempleado);
respuesta = beanBuscadorEmpleados.buscarEmpleado(idempleado);
out.println(respuesta);
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Solamente nos quedaría realizar la llamada al Servlet. Para ello, sobre el proyecto WAR vamos a
seleccionar la página que trae por defecto index.jsp y la implementaremos para enviar el ID del
empleado y utilizar la tecnología EJB para encontrarlo.

<%@page contentType="text/HTML" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form name="form1" action="ServletEmpleado">
Escriba el ID del empleado a buscar
<input type="text" name="txtnumero"><br>
<input type="submit" value="Buscar Empleado">
</form>
</body>
</HTML>

Debemos recordar que las aplicaciones empresariales son un conjunto de elementos y contenedores
de los objetos, por lo que debemos ejecutarla en su conjunto con la tecla F6.
Cuando ejecutemos nuestra aplicación, veremos la página inicial index.jsp con el diseño que
hayamos realizado.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Una vez que pulsemos sobre el botón, comprobaremos que la respuesta desde el EJB llega
correctamente.

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 8. La persistencia API de Java

Introducción
Java Persistence Api es el estándar para gestionar la persistencia de Java, definida como parte de la
versión EJB 3.0 y que trabaja con elementos llamados POJO’s.
Se trata de manejar las entidades de base de datos como objetos Java, o lo que es lo mismo, dotar
de persistencia a los objetos del lenguaje Java.
Dichos elementos POJO’s son clases EJB’s de entidad que permiten manejar objetos persistentes
dentro de la base de datos utilizando el contenedor como conector con dicho origen de datos.
El principal componente de la arquitectura es el objeto Entity Manager.
Normalmente, en un servidor de aplicaciones con contenedor de EJB esta entidad nos será
proporcionada y no es necesario recurrir al factory.
La clase Persistence dispone de métodos estáticos que permiten obtener una instancia del objeto
Entity Manager Factory de forma independiente al proveedor de JPA y a partir del que se puede
obtener el Entity Manager necesario.
Mediante EntityManager podemos obtener objetos Query para realizar consultas sobre la base de
datos y para cargar objetos persistidos con determinados criterios.
JPA emplea el lenguaje de consulta JPQL ó SQL. También podemos realizar operaciones CRUD sobre
los objetos persistentes Entity.
Cada instancia de EntityManager tiene una relación uno a uno con una Entity Transaction,
permitiendo el manejo de operaciones sobre objetos persistentes con la idea global de transacción,
de forma que se ejecuten todas las operaciones o ninguna.
La unidad de persistencia es el objeto que aporta información necesaria para enlazar con la base de
datos relacional adecuada.

Objetivos
 Conocer las características de creación de objetos persistentes en Java.
 Concepto de POJO y Entity Beans dentro del entorno de Java EE.

Beans de Entidad
Los EJB de entidad están directamente relacionados con los datos de la aplicación, son objetos que
mantienen en memoria los datos que maneja la aplicación, las entidades que disponen de
persistencia, Noticias, Usuarios, Clientes, etc...
Los Beans de Entidad pueden crear un mapeo de las tablas de una base de datos relacional, aunque
también es posible que mantengan la persistencia de los datos en ficheros, por ejemplo un XML, o
en LDAP.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
En cualquiera de los casos, el objetivo de un Bean de Entidad es almacenar los datos en memoria
desde una fuente persistente y mantener una sincronización total entre el estado de los datos, la
memoria y la fuente de datos.
Este tipo de EJB abstrae totalmente la capa de persistencia del sistema y funciona como una
herramienta de traducción de base de datos relacional a objeto.
Dentro de los Beans de Entidad hay dos formas de manejar la persistencia, se puede dejar en
manos del programador de los Beans o en manos del contenedor CMP.
En el primer caso la responsabilidad de cómo y dónde se almacenan los datos recae en la reescritura
de los métodos necesarios por parte del programador.
En el segundo caso sólo hay que especificar los tipos de acceso en declaraciones de métodos y el
Servidor de Aplicaciones donde se ejecuten dichos métodos. El contenedor de se encargará de
automatizar el proceso sin necesidad de programación extra de código por parte del programador.
Ciclo de vida de Entity

El ciclo de vida de una entidad, maneja dos aspectos, la relación entre el objeto Entidad y su
contexto a persistir y la sincronización de su estado con la base de datos.
Para realizar estas operaciones la Entidad puede encontrarse en cualquiera de estos cuatro estados:
 New: Nueva instancia de la Entidad en memoria sin que aún se le haya asignado su contexto
persistente almacenado en la tabla de la base de datos.
 Managed: La Entidad dispone de contenido asociado con el de la tabla de la base de datos
debido a que se utilizó el método persist().
Los cambios que se produzcan en la Entidad se podrán sincronizar con los de la base de datos
llamando al método flush().
 Detached: La Entidad se ha quedado sin su contenido persistente. Es necesario utilizar el
método merge() para actualizarla.
 Removed: Estado que se ejecuta después de llamar al método remove() y el contenido de la
Entidad será eliminado de la base de datos.

Anotaciones de entidades POJO’s


Una entidad JPA no es más que un POJO que dispone de una serie de anotaciones, que indican qué
y cómo se persiste un objeto.
Estas anotaciones vinculan cada propiedad del POJO con las de la base de datos y establecen un
vínculo directo.
Anotación @Entity

Indica que el objeto es una entidad.


A través de la anotación Table se indica la tabla de base de datos que contiene objetos de este tipo.
Ejemplo de código:
@Entity
@Table(name="PRODUCTOS")

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
public class Producto {
@Id
private String nombreproducto;
public Producto() { }
//METODOS Getters y Setters
}
Toda entidad debe tener una clave primaria que se debe identificar con la anotación @Id. Además,
todas las entidades deben contener un constructor vacío.
Como norma debe emplearse un nombre singular para las clases Java y plural para las tablas de
base de datos que las contengan.
Anotaciones @Id, @IdClass, @EmbeddedId

Se emplean para declarar claves primarias de clases, bien de forma simple @Id o compuesta
@IdClass y @EmbeddedId.
En el caso de las claves compuestas se debe definir una clase para representar a la clave primaria, y
redefinir el método equals para comprobar que dos instancias de una clase sean iguales.
Veamos un código utilizando @IdClass
@Entity
@IdClass(PersonaId.class)
public class Persona {
@Id
private int id;
@Id
private String nombre;
...
public Persona() { }
//METODOS Getters y Setters
}

public class PersonaId {


int id;
String nombre;
public boolean equals(Object o) {
// Codigo que comprueba si las dos entidades son iguales
}
}
Y ahora un código utilizando @EmbeddedId
@Entity
public class Persona {
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "id", column = @Column(name = "ID",
nullable = false, precision = 5, scale = 0)),
@AttributeOverride(name = "nombre", column = @Column(name = "NOMBRE"
nullable = false, length = 50)),
})
private PersonaId id;
public Persona() { }
//Métodos Getters y Setters
}

@Embedded
public class PersonaId {

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
int id;
String nombre;
public PersonaId() { }
public boolean equals(Object o) {
// Codigo que comprueba si las dos entidades son iguales
}
}
La recomendación es usar @EmbeddedId y usar el nombre de la clase con el sufijo Id para la clave
primaria.
Para generar los valores de una clave primaria, es decir, que los genere JPA automáticamente,
podemos utilizar la anotación @GeneratedValue.
Esta anotación genera la clave primaria de cuatro formas diferentes:
 AUTO: Es el valor por defecto, y deja al proveedor de persistencia elegir cual de las
siguientes tres opciones va a utilizar.
 SEQUENCE: Utiliza una secuencia SQL para obtener el siguiente valor de la clave primaria.
 TABLE: Necesita una tabla con dos columnas, el nombre de la secuencia y su valor (es la
estrategia por defecto utilizada en el conector TopLink).
 IDENTITY: Utiliza un generador de identidad como las columnas definidas con
auto_increment.
Anotación @Column

JPA define que los tipos primitivos, clases "envoltorio" o “wrappers” de tipos primitivos, son
mapeados de forma automática en columnas, es decir, no es necesario marcarlos.
Los tipos wrappers o envueltos de Java son:
 java.lang.String
 byte[]
 Byte[]
 char[]
 Character[]
 java.math.BigDecimal
 java.math.BigInteger
 java.util.Date
 java.util.Calendar
 java.sql.Date
 java.sql.Timestamp
Además todos aquellos objetos que sean de tipo Serializable y estén marcados con la anotación
@Basic.
Si lo que queremos es que una variable, de las que son mapeadas de forma automática, no sea
tomada como un campo del origen de la base de datos, debemos usar la anotación @Transient.
Además tenemos diferentes formas de mapear cada campo indicando nombres de columna y otros
valores.
@Entity
@Table(name="PRODUCTOS")
public class Productos {
@Id
private String nombreproducto;
@Column(name="CATEGORIA", nullable=false)
private String categoria;
@Column(name="DESCRIPCION", nullable=false)
private String descripcion;
@Lob
@Basic(fetch=FetchType.LAZY)
private byte[] imagen;

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
public Productos() { }
//Métodos Getters y Setters
}
La anotación @Column permite definir varias propiedades.
La propiedad name puede especificar el nombre de la columna donde va a ser persistido el campo,
si esta propiedad no está presente en el framework de persistencia, usará el nombre de la variable
como nombre de la columna.
La propiedad nullable indica si la columna acepta valores null o no, si no se incluye el valor por
defecto es true.
Además, esta anotación soporta otras muchas propiedades como pueden ser columnDefinition,
length, precision, scale, insertable, updatable y table para definir propiedades específicas de la
columna.
La anotación @Basic sirve para marcar cualquiera de los tipos de datos que son persistidos de forma
automática además de las clases que sean Serializables
La propiedad optional funciona igual que la propiedad nullable de la anotación @Column.
La propiedad fetch permite definir cuándo se debe cargar el campo en cuestión, el valor
FetchType.LAZY indica que el campo se va a cargar de forma "perezosa", es decir, el campo se
cargará sólo cuando se acceda a su información, esto supone una consulta más para la obtención
del campo, pero en casos de gran cantidad de información es muy beneficioso.
El valor FetchType.EAGER indica que el valor será cargado cuando se cargue el resto del objeto.
El valor por defecto de la propiedad fetch es FetchType.EAGER.
La anotación @Lob indica que el contenido de un campo básico será guardado como LOB (Large
Object).
Si por ejemplo, utilizamos esta anotación para marcar un campo que contenga un String o
caracteres, el framework lo mapeará a una columna CLOB (Character Large Object).
Si es de otro tipo, normalmente byte[], será mapeado a una columna de tipo BLOB (Binary Large
Object).
Anotación @Embeddable

Esta anotación sirve para designar objetos persistentes que no tienen la necesidad de ser una
entidad por si mismas.
Esto se debe a que los objetos Embeddable son identificados por los objetos entidad, estos objetos
nunca serán persistidos o accedidos por si mismos, sino como parte del objeto entidad al que
pertenecen.
@Entity
@Table(name="PERSONAS")
public class Persona {
@Id
private String nombre;
@Embedded
@AttributeOverrides({@AttributeOverride(name="codigoPostal",
column=@Column(name="CODIGOPOSTAL")),
@AttributeOverride(name="direccionPostal",
column=@Column(name="DIRECCIONPOSTAL"))
})
private Direccion direccion;
public Persona() { }
//Métodos Getters y Setters
}

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
@Embeddable
public class Direccion implements Serializable {
private String direccionPostal;
private String ciudad;
private int codigoPostal;
private String pais;
public Direccion() { }
public boolean equals(Object o) {
// Codigo que comprueba si las dos entidades son iguales
}
}
Los campos contenidos en la clase marcada como @Embeddable son columnas de la entidad a la
que pertenecen y son cargadas, de la base de datos, a la vez que la entidad.
Anotación @OneToOne

La anotación @OneToOne es usada para marcar relaciones unidireccionales y bidireccionales.


Sirve para crear relaciones entre otras entidades que tengamos declaradas:
@Entity
@Table(name="PRODUCTOS")
public class Producto {
@Id
private String nombreproducto;
@Column(name="DESCRIPCION", nullable=false)
private String descripcion;
@OneToOne
@JoinColumn(name="CATEGORIA _ID",
referencedColumnName="CATEGORIA_ID", updatable=false)
private Categoria categoria;
public Producto() { }
//Métodos Getters y Setters
}
@Entity
@Table(name="CATEGORIAS")
public class Categoria {
@Id
@Column(name=" CATEGORIA_ID")
private int id;
@Column(name="NOMBRECATEGORIA", nullable=false)
private String nombrecategoria;
public Categoria() { }
//Métodos Getters y Setters
}
Anotación @OneToMany

La asociación de 1-N es la más común que nos vamos a encontrar en cualquier base de datos y
cualquier JPA.
En este tipo de relación, una entidad tiene dos o más referencias de otra.
Poniendo un ejemplo, podemos tener una tabla de jugador y otra de equipo. Un equipo puede
contener varios jugadores, pero un jugador sólo puede estar en un equipo.
Esta relación sería:
@Entity
@Table(name="EQUIPOS")
public class Equipo {
...
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
private Set<Jugador> jugadores = new HashSet<Jugador>(0);
//Métodos Getters y Setters
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
mappedBy = "equipo")
public Set<Jugador> getJugadores() { return this.jugadores; }
public void setJugadores(Set<Jugador> jugador) { this.jugadores = jugador; }
...
}
La anotación @OneToMany indica que un equipo puede contener varios jugadores.
La anotación @OneToMany tiene una propiedad llamada cascade que define el tipo de operaciones
se realizarán cuando se efectúen modificaciones sobre los datos de la entidad.
La propiedad cascade, puede tomar los siguientes valores:
 CascadeType.PERSIST: Cuando persistimos una entidad, todas las entidades que contenga
esta variable serán persistidas también.
 CascadeType.REMOVE: Cuando eliminemos una entidad, todas las entidades que contenga
esta variable se borrarán del mismo modo.
 CascadeType.REFRESH: Cuando actualicemos la entidad, todas las entidades que contenga
esta variable se actualizarán.
 CascadeType.MERGE: Cuando hagamos un "merge" de la entidad, todas las entidades que
contenga esta variable realizarán la misma operación.
 CascadeType.ALL: Todas las operaciones citadas anteriormente.
La propiedad mappedBy = "equipo" indica el nombre de la entidad Equipo en el objeto Jugador.
Anotación @ManyToMany

La asociación N-N es muy común, aunque no tanto como la anterior.


Esta relación es una de las más complicadas a la hora de ser manejada, ya que implica tablas
intermedias para la relación.
Volviendo al ejemplo de equipos y jugadores, la anotación @ManyToOne indicaría que varios
jugadores pueden haber sido inscritos en diferentes equipos.
Anotaciones del ciclo de vida

Existen otra serie de anotaciones adicionales que nos pueden ser útiles para programar aspectos o
afinar en la interacción con la base de datos.
 @EntityListeners: Se pueden definir clases listeners con métodos de ciclo de vida de una
entidad.
Para hacer referencia a un listener, se debe incluir esta anotación seguido de paréntesis de la clase:
@Entity
Listeners(MyListener.class)
 @ExcludeSuperclassListeners: Indica que ningún listener de la superclase será invocado por
la entidad ni por ninguna de sus subclases.
 @ExcludeDefaultListeners: Indica que ningún listener por defecto será invocado por esta
clase ni por ninguna de sus subclases.
 @PrePersist: El método se llamará justo antes de la persistencia del objeto. Podría ser
necesario para asignarle la clave primaria a la entidad a persistir en base de datos.
 @PostPersist: El método se llamará después de la persistencia del objeto.
 @PreRemove: El método se llamará antes de que la entidad sea eliminada.
 @PostRemove: El método se llamará después de eliminar la entidad de la base de datos.
 @PreUpdate: El método se llamará antes de que una entidad sea actualizada en base de
datos.
 @PostUpdate: El método se llamará después de que la entidad sea actualizada.
 @PostLoad: El método se llamará después de que los campos de la entidad sean cargados
con los valores de su entidad correspondiente de la base de datos. Se suele utilizar para
inicializar valores no persistidos.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 @FlushMode: Modo en que se ejecuta la transacción: FlushModeType.AUTO (por defecto) y
FlushModeType.COMMIT.
 @NamedQuery: Especifica el nombre del objeto query utilizado junto a un EntityManager.

Sus atributos son:


o name - nombre del objeto query.
o query - especifica la query a la base de datos mediante lenguaje Java Persistence
Query Language (JPQL)
 @NamedQueries: Específica varias queries como la anterior.

Búsquedas de datos en Entidades


Una vez que tenemos las entidades, podemos realizar consultas de acción sobre los objetos
utilizando las clases POJO’s.
Para realizar búsquedas dentro de las entidades, podemos utilizar varios métodos.
La forma más sencilla de buscar en un Entity Bean es utilizar el método find(Class, Object) de la
interfaz EntityManager.
Este método permite buscar un Entity por su clave primaria.
Para buscar un producto, por ejemplo, podríamos usar el siguiente código:
Producto product = entityManager.find(Producto.class, new Long(1));
El primer parámetro del método find es la clase del Entity que deseamos buscar.
El segundo parámetro, la clave primaria del Entity.
La clase que pasemos como parámetro debe ser anotada con @Entity.
Búsquedas con JPQL
JPA ofrece una API para realizar tanto consultas como operaciones masivas sobre Entity Beans
(actualizaciones y eliminaciones).
Esta API involucra tres componentes:
 Métodos de consulta del EntityManager.
 La interfaz javax.persistence.Query.
 El lenguaje JPQL (Java Persistence Query Language).
Lenguaje JPQL
Seguramente, en nuestra aplicación deberemos realizar búsquedas más complejas que solamente
por la clave primaria de un objeto.
JPQL es un lenguaje que permite crear tres tipos de sentencias (consulta, actualización y
eliminación), y que opera sobre Entity Beans.
Presenta una sintaxis similar a SQL, pero no está orientado a un modelo relacional (basado en tablas
y columnas) sino a un modelo de objetos (objetos y atributos).
Permite al programador independizarse de la base de datos y del esquema relacional.
Comenzaremos viendo algunos ejemplos de consultas sencillas utilizando este lenguaje. Pongamos
como ejemplo una Entidad Empleado que está compuesto por los siguientes campos:
 EmpleadoId
 Nombre
 Oficio
 Salario
 FechaAlta
 Departamento

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Debemos recordar que las Entidades son sensibles a mayúsculas y minúsculas en los nombres de la
Entidad y los campos.
Si queremos recuperar todos los datos de un empleado:
SELECT e FROM Empleado e
La cláusula from no se refiere a una tabla, sino a una clase, en nuestro ejemplo, la clase Empleado.
El resultado de la consulta no es un conjunto de columnas, sino un objeto, un Entity Bean.
Para ejecutar esta consulta, debemos utiliza el EntityManager en conjunto con la interfaz
javax.persistence.Query.
Query consulta = entityManager.createQuery("SELECT e FROM Empleado e");
List<Empleado> empleados= consulta.getListResult();
Dentro de entity Framework, tenemos dos tipos de consultas para utilizar el lenguaje JPQL:
Consultas dinámicas

Son aquellas consultas que no están definidas de manera fija, sino que se construyen en tiempo de
ejecución.
Después de construir la consulta, se utiliza el método EntityManager.createQuery(String) para
obtener el objeto Query que la representa.
El anterior código es un ejemplo de una consulta dinámica.
Cada ejecución del método EntityManager.createQuery crea una nueva instancia de
javax.persistence.Query.
Este tipo de consultas no está pesado para ser reutilizado.
Consultas estáticas

Son consultas cuya definición no varía en tiempo de ejecución.


Están pensadas para ser reutilizadas muchas veces.
Se las puede definir en la clase de un Entity Bean.
Favorecen la mantenibilidad y legibilidad del código, y pueden aumentar la performance ya que se
preparan una sola vez y luego se reúsan cada vez que son llamados.
Para definirlas en la clase de un EntityBean, se utilizan las anotaciones @NamedQuery y
@NamedQueries.
Para definir una única consulta en la clase de un Entity Bean:
@Entity
@Table(name = "EMPLEADOS")
@NamedQuery(name="todosempleados", query="SELECT e FROM Empleado e")
public class Empleado {
//Métodos y elementos de la clase Empleado
}
Para definir más de una consulta dentro de un entity Bean se utiliza la anotación @NamedQueries
que contiene un conjunto de consultas.
@Entity
@Table(name = "Empleado")
@NamedQueries(value={
@NamedQuery(name=" todosempleados", query="SELECT e FROM Empleado e")
, @NamedQuery(name=" todosempleadosorden", query="SELECT e FROM Empleado e ORDER BY
e.Nombre")}
)
public class Empleado {

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
//Métodos y elementos de la clase Empleado
}
Para ejecutarlas debemos utilizar el método EntityManager.createNamedQuery(String), pasando
como parámetro el nombre de la consulta, definido en el atributo name de la anotación
@NamedQuery correspondiente:
Query consulta = entityManager.createNamedQuery("todosempleados");
List<Empleado> empleados = consulta.getResultList();
Parametrización de consultas

Una consulta puede parametrizarse mediante 2 tipos de parámetros:


 Posicionales
 Por nombre de parámetro
Para utilizar parámetros posicionales, el parámetro debe indicarse en la cláusula where de la
consulta con el prefijo ?, y a continuación el número posicional del parámetro.

SELECT e FROM Empleado e WHERE e.Nombre = ?1


Luego, al ejecutarla, se establece el valor del parámetro según su posición:
Query consulta = entityManager.createQuery("SELECT e FROM Empleado e WHERE e.Nombre =
?1");
consulta.setParameter(1, "SHUM");
Empleado emp = consulta.getSingleResult();
Para utilizar parámetros por nombre, el parámetro debe indicarse en la cláusula where de la
consulta con el prefijo: y a continuación el nombre del parámetro:

SELECT e FROM Empleado e WHERE e.Nombre = :nombreempleado


Posteriormente, al ejecutarla, se establece el valor del parámetro según su nombre:
Query consulta = entityManager.createQuery("SELECT e FROM Empleado e WHERE e.Nombre =
:nombreempleado");
consulta.setParameter("nombreempleado", "SHUM");
Empleado emp = consulta.getSingleResult();
Ambos estilos de parametrización pueden usarse en consultas estáticas como dinámicas,
indistintamente.
Vamos a visualizar un ejemplo en el que crearemos un acceso a la base de datos Oracle y nos
generaremos tablas desde entidades creadas en nuestro proyecto.
Nos creamos un nuevo proyecto.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo llamaremos AplicacionJTA.

Utilizaremos el servidor GlassFish y no seleccionaremos ningún Framework.

Ahora sobre nuestro proyecto, vamos a agregarnos una unidad de persistencia que es el objeto
encargado de conectar nuestras entidades con la base de datos.
Seleccionamos New  Other.

En la pestaña de Persistence, seleccionamos el objeto Persistence Unit.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora nos debemos de crear una conexión sobre la base de datos Oracle. Dicha conexión quedará
guardada en nuestro IDE NetBeans para futuras acciones.
Seleccionamos del desplegable Data Source la opción New Data Source…

Nos aparecerá una ventana en la que debemos seleccionar la conexión de la base de datos y el
nombre del JNDI. Como JNDI pondremos CONNECTIONORACLE y seleccionaremos la opción New
Database Connection…

Tendremos un desplegable dónde nos mostrarán los diferentes drivers para conexión de base de
datos instalados con NetBeans. Seleccionamos New Driver.

Buscamos el driver de Oracle.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Una vez que hemos seleccionado nuestro driver de Oracle, debemos configurar los elementos
necesarios para trabajar con el servidor.
Host: LOCALHOST
PORT: 1521
SERVICE ID: XE
USER NAME: SYSTEM
PASSWORD: 12345 (Password que hayamos creado para SYSTEM en Oracle)

Pulsamos en siguiente y nos mostrará una pantalla en la que podríamos seleccionar el propietario de
la base de datos desde el que deseamos visualizar las tablas.
Dejamos por defecto nuestro usuario SYSTEM y finalizamos.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora ya habremos vuelto a la ventana de Persistence Unit.
La opción más importante es CREATE o DROP AND CREATE.
Dichas opciones, permiten crear la base de datos o eliminar la base de datos (si existe) para
posteriormente eliminarla.
Si la base de datos existiera, la eliminaría para crearla!!!

Como podemos comprobar en la unidad de persistencia, podríamos cambiar las opciones cuando lo
necesitemos.

Nos habrá creado un fichero persistence.xml.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora nos vamos a crear un paquete para poner ahí las entidades.

Lo llamaremos packagejta

Sobre nuestro paquete, incluiremos una nueva Entity Class desde la carpeta Persistence.

Nuestra clase se llamará Jugador y nos crearemos una clave primary key de tipo Integer.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora vamos a implementar propiedades y características de la clase.
Nos creamos tres propiedades.
private String NombreJugador;
private String Posicion;
private int Calidad;
Vamos a encapsular los campos y crearnos sus métodos Getter y Setter.

Ahora vamos a implementar algo el código de la clase con constructores para facilitarnos la
programación posterior.
public Jugador()
{
this.NombreJugador = "";
this.Posicion = "";
this.Calidad = 0;
}
public Jugador(int idjugador, String nombrejugador, String posicion, int calidad)
{

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
this.id = idjugador;
this.NombreJugador = nombrejugador;
this.Posicion = posicion;
this.Calidad = calidad;
}
La creación de la tabla jugador en la base de datos la realizaremos desde un Servlet.
Nos creamos un nuevo Servlet sobre el proyecto.

Lo llamaremos ServletJTA

Incluimos su información en el descriptor de despliegue de la aplicación.

Ahora vamos a utilizar el editor de NetBeans para generarnos los objetos de la unidad de
persistencia. Para ello, seleccionamos con el botón derecho sobre nuestro código Persistence  Use
Entity Manager

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Nos generará un método para acceder a la unidad de persistencia. Nosotros vamos a cambiar su
código para adaptarlo y lo renombraremos. Este es el código del método que debemos realizar.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("AplicacionJTAPU");
public void CrearBBDD()
{
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
ArrayList<Jugador> jugadores = new ArrayList<Jugador>();
Jugador j = new Jugador();
j.setId(1);
j.setNombreJugador("Iniesta");
j.setCalidad(9);
j.setPosicion("Mediapunta");
jugadores.add(j);
j = new Jugador();
j.setId(2);
j.setNombreJugador("Xavi Alonso");
j.setCalidad(8);
j.setPosicion("Mediocentro");
jugadores.add(j);
j = new Jugador();
j.setId(3);
j.setNombreJugador("Iker Casillas");
j.setCalidad(10);
j.setPosicion("Portero");
jugadores.add(j);

for (Jugador jugador : jugadores)


{
em.persist(jugador);
}
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
} finally {
em.close();
}
}
Ahora vamos a implementar la llamada al servlet.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
this.CrearBBDD();
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet ServletJTA</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>DATOS CREADOS CORRECTAMENTE</h1>");
out.println("</body>");
out.println("</HTML>");
} catch (Exception e) {
out.println("<HTML>");

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
out.println("<head>");
out.println("<title>Servlet ServletJTA</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>EXCEPCION!!</h1>");
out.println("<h1>"+e.toString()+"</h1>");
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();
}
}

A continuación, vamos a escribir un formulario en la página index.jsp que realizará la llamada al


Servlet
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form name="form1" action="ServletJTA">
<input type="submit" value="Crear BBDD con jugadores">
</form>
</body>
</HTML>
Por último, agregamos el driver oracle

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
La estructura de nuestro proyecto quedaría de la siguiente forma:

Ejecutamos la aplicación completa con la tecla F6 y comprobaremos su resultado.

Si hacemos la consulta a Oracle, veremos que ha almacenado los datos correctamente.

Ver Video: Consultas de Empleados, en la Unidad 8, en el


Módulo 4, en la plataforma elearning

Laboratorio: Buscador de departamentos


Objetivos
 Conocer el de la tecnología EJB con Beans de entidad.
 Persistencia de objetos y consultas a bases de datos mediante objetos POJO’s.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Enunciado
Vamos a realizar una aplicación que buscará un departamento y devolverá sus datos utilizando para
la lógica un Bean de entidad.
Para ello, utilizaremos la tecnología EJB y acceso a la base de datos mediante unidades de
persistencia.
Lo primero que vamos a realizar será crearnos un nuevo proyecto web Application.

Dejaremos todos los valores por defecto.


Sobre nuestro proyecto, vamos a agregarnos una unidad de persistencia, para ellos seleccionamos
Persistence Unit.

Dejaremos el nombre de la unidad de persistencia por defecto WebApplication3PU.


Seleccionaremos un proveedor, Toplink en nuestro ejemplo y configuraremos un acceso a datos
como hemos aprendido en el módulo. Nuestro origen de datos se llama CONEXIONORACLE.
Marcaremos None como estrategia de generación de la tabla.

Es imprescindible poner NONE para que no elimine los registros ni las tablas del servidor,
de esta forma, todo quedará administrado y mantendrá los datos originales de las tablas.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Veremos que nos ha creado el fichero persistence.xml para administrar nuestros objetos Entity de la
base de datos.

A continuación, vamos a crearnos un nuevo paquete que llamaremos packageJTA.

Sobre nuestro paquete generado, vamos a agregar los objetos de la base de datos para trabajar.

Agregaremos un objeto Entity Classes from Database de la carpeta Persistence.

Buscamos las tablas que vayamos a agregar como entidades de la base de datos. En nuestro
ejemplo, utilizaremos la tabla DEPT.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Dejamos los valores por defecto en la siguiente pantalla.

En las opciones de mapeo de la entidad, marcamos la colección como Collection.

Ahora vamos a agregar un servlet para poder hacer las consultas sobre las entidades.
Agregamos un servlet y escribimos el siguiente código:
package packageJTA;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import javax.persistence.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class NewServlet extends HttpServlet {
private void Pintar(PrintWriter out, short iddept)
{
EntityManagerFactory emf = Persistence.createEntityManagerFactory("WebApplication3PU");
EntityManager em = emf.createEntityManager();
Query consulta = em.createQuery("SELECT d FROM Dept d");
List<packageJTA.Dept> listadept = consulta.getResultList();
Dept dep = em.find(Dept.class,iddept);
if (dep == null)
{
out.println("<h4>No se ha encontrado el departamento</h4>");
}else{

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
out.println("Departamento encontrado: "+ dep.getDname());
}
out.println("<h4>Lista de departamentos</h4>");
out.println("<table border='1'>");
for (packageJTA.Dept d : listadept)
{
out.println("<tr>");
out.println("<td>"+d.getDeptno()+"</td>");
out.println("<td>"+d.getDname()+"</td>");
out.println("<td>"+d.getLoc()+"</td>");
out.println("</tr>");
}
out.println("</table>");
out.println("<a href=index.jsp'>Volver a la busqueda</a>");
}

protected void processRequest(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet NewServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>DATO ENCONTRADO!!</h1>");
String departamento = request.getParameter("txtnumero");
short iddept = Short.parseShort(departamento);
this.Pintar(out, iddept);
out.println("</body>");
out.println("</HTML>");
}catch (Exception ex)
{
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet NewServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>EXCEPCION</h1>");
out.println(ex.toString());
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
}
Después una página JSP para la llamada al servlet:
<%@page import="java.util.List"%>
<%@page import="javax.transaction.Transaction"%>
<%@page import="javax.persistence.*"%>
<%@page import="packageJTA.*"%>
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form name="form1" action="NewServlet">
Numero departamento:
<input type="text" name="txtnumero"/>
<input type="submit" value="Buscar departamento"/>
</form>
</body>
</HTML>
Y el resultado es:

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 9. Implementando una política
transaccional

Introducción
Una transacción es una operación atómica, es decir, se realizan una serie de operaciones de forma
completa, o no se realiza ninguna.
Por ejemplo, si tenemos que hacer una transferencia de una cuenta a otra en un banco, las dos
operaciones forman un conjunto. No sería lógico que quitásemos efectivo de una cuenta y, por
alguna razón, no pudiéramos ingresar el dinero en la cuenta de destino, o se realizan las dos
operaciones o ninguna. Nunca debería quedar esta operación con un estado inconsistente, es decir,
un estado en el cual hayamos realizado la primera operación, pero no la segunda.
En las bases de datos esto se logra mediante el inicio de transacciones. Una vez iniciada una
transacción, ningún cambio queda reflejado hasta que no se confirmen las operaciones ("commit"),
o se anulen las mismas ("rollback").
El API de Java para manipular transacciones se conoce como JTA (Java Transaction Api).
En las aplicaciones JEE es muy poco habitual realizar commits o rollbacks explícitamente, en cambio,
se suelen utilizar algunas técnicas para poder "deducir" cuándo se tiene que realizar commit o
rollback.

Objetivos
 Comprender el concepto de la lógica transaccional de aplicaciones.
 Conocer el modelo transaccional JTA que proporciona la tecnología Java EE.

Conceptos clave de transacciones


Uno de los principales retos que enfrentan las empresas al desarrollar nuevo software que inter
opere con otras aplicaciones existentes es la integración y consistencia de los datos.
En muchas empresas se cuenta con fuentes de datos heterogéneas, incluso con redundancia de
información en muchos casos.
Desafortunadamente otras aplicaciones corren sobre esas fuentes de datos, lo que implica
que nuevas aplicaciones no pueden alterar la estructura de la información debido a que dejaría
sin funcionamiento a otras aplicaciones dependientes.
La manipulación de fuentes de datos heterogéneas es un problema que puede ser subsanado
mediante el uso de APIs que encapsulen el acceso a los datos.
A pesar de ello, es necesario contar con las garantías que proveen las fuentes de datos en
forma independiente a nivel global, es decir, contar con poder transaccional sobre las múltiples
fuentes heterogéneas.
La gestión transaccional es un pilar importante en la plataforma J2EE. La misma especifica
cómo llevar adelante transacciones globales sobre múltiples fuentes de datos heterogéneas.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El poder transaccional no solo radica en las fuentes de datos, sino que es extendido a objetos en
memoria, lo cual aumenta fuertemente su poder.
Existen tres conceptos de transacciones que son importantes para el desarrollo de aplicaciones Java
EE.
 Atomicidad

Las operaciones son un conjunto completo, o todas se realizan bien o si falla alguna, fallan todas a
la vez.

 Locking and Isolation

Dicho término implica que solamente una transacción puede actualizar un dato al mismo tiempo.
La técnica de Optimistic Locking proporciona mejor concurrencia y posibilidades de crecimiento
(scalability) porque permite que múltiples transacciones accedan a los mismos datos.
En la API de Persistencia de Java, el Optimistic Locking se implementa mediante el rastreo de
versiones que incluye un número de versión en las Entidades.
Si se intenta modificar una Entidad que usa Optimistic Locking y los datos persistentes de la Entidad
fueron modificados por otra transacción, la transacción actual termina con la excepción
OptimisticLockException.

 Modelo

Cuantas transacciones pueden estar activas en un mismo thread (hilo) en particular en un momento
dato.
Existen varios modelos de transacciones:
 Anidado (Nested)

Una transacción consta de varias sus transacciones que corren en paralelo todas juntas.
 Encadenado (Chained)

Una transacción consta de varias subtransacciones que corren en secuencia.


 Plano (Flat): Una transacción no puede contener subtransacciones.

La plataforma Java EE solamente soporta el modelo plano.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Especificaciones transacción JEE
La Plataforma J2EE (Java 2 Enterprise Edition) define un conjunto de estándares para el
desarrollo de aplicaciones empresariales en múltiples capas.
La plataforma simplifica estas aplicaciones basándolas en componentes modulares estándar,
incluyendo un conjunto de servicios a dichos componentes y manejando muchos detalles del
comportamiento en forma automática, sin necesidad de programación compleja.
Un pilar fundamental de toda aplicación empresarial es el soporte transaccional.
El servicio de transacciones distribuidas de la Plataforma J2EE involucra cinco participantes
diferentes:
 Transaction Manager (TM): Es el encargado de proveer los servicios para demarcación de
transacciones, manejo de recursos transaccionales, sincronización y propagación de contexto
transaccional.
 Application Server: Implementa los servicios necesarios para proveer un entorno de
ejecución para las aplicaciones. Entre estos servicios está el manejo del estado transaccional.
 Resource Manager (RM): Ofrece a las aplicaciones acceso a recursos. Este acceso se ofrece
a través de Resource Adapters. Este participa de transacciones implementado una interfaz
para el manejo de recursos transaccionales, que controla la asociación a una
transacción, la finalización de una transacción y la recuperación de una transacción.
 Aplicación basada en componentes transaccionales: Esta aplicación se ejecuta sobre un
servidor de aplicaciones, el cual le ofrece, entre otros servicios, control de transacciones,
como por ejemplo, una aplicación basada en Enterprise Java Bean.
 Communication Resource Manager: Encargado de la propagación del contexto
transaccional permitiendo acceder a recursos transaccionales ubicados en otros dominios.

El soporte del poder transaccional en los sistemas informáticos ha sido bien resuelto a
nivel de manejadores de bases de datos. En las aplicaciones pequeñas y medianas el manejo de
los datos persistentes goza de las propiedades ACID garantidas por los motores de bases de datos
que son utilizados de forma directa.
Las operaciones transaccionales en la plataforma JEE surgen por la posible necesidad de un
desarrollador para mantener información en memoria relacionada con la información en la
base de datos.
Otra de las soluciones que se han ofrecido sobre las transacciones en JEE surge cuando una
aplicación debe manipular información que radica en distintas bases de datos, es en ese momento
cuando nace la necesidad de contar con un agente externo que se encargue de controlar dicha
transacción.
De esta forma, los monitores transaccionales aparecen como solución a dicho problema.
La plataforma J2EE da un paso en ambas direcciones: poder transaccional a nivel de
componentes en memoria y manipulación de información en distintas fuentes de datos.
Mediante la tecnología de EJB, dichas soluciones han podido resolverse y se han creado
especificaciones para poder obtener elementos transaccionales independientes a la base de datos, lo
que permite poder utilizar un componente que puede manejar diferentes transacciones entre
diferentes orígenes de datos.
La especificación de EJB incluye consideraciones respecto al manejo transaccional.
Existen dos formas de representar las transacciones sobre las cuales el sistema está sujeto:
 Mediante programación. Existe un bean que controla la transacción. Esta forma se llama
Bean-Managed Transaction (BMT).

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 De forma declarativa. El desarrollador solamente debe establecer de forma declarativa
como quiere que el contenedor maneje las transacciones. Esta forma lleva el nombre
de Container-Managed Transactions (CMT).
En la primera especificación de EJB se propusieron dos modelos de componentes, conocidos como
Entity Bean y Session Bean. La especificación 2.0 introduce un nuevo modelo de componente
llamado Message Driven Bean.

Transacciones con Entity Beans


El objetivo de los entity beans es representar entidades con estado persistente.
Podemos definirlos como la representación orientada a objetos de la información que reside en las
fuentes de datos (resources).
Dichos Beans permiten realizar acciones transaccionales y su funcionalidad reside en el control total
del origen de los datos, independientemente de dicho origen.
Los entity beans son la representación de datos persistentes. El manejo de persistencia puede ser
realizado por el propio bean (BMP) o por el contenedor (CMP).
Si realizamos una transacción dentro de un Entity Bean, el programador es el encargado de escribir
explícitamente los límites y características de la transacción.
La transferencia de datos entre el entity bean y la fuente de datos es llevada a cabo por los
métodos ejbLoad() y ejbStore().
La sincronización de los datos en memoria con los datos en la fuente de datos es
responsabilidad del contenedor.
Dicho contenedor logra este objetivo invocando el método ejbLoad() en el momento que sea
necesario. De esta forma, realizando ejbLoad() cuando una transacción ha abortado se logra el
rollback de los datos en memoria.

Session Beans
El objetivo de los session beans es encapsular los procesos de negocios que conforman al sistema.
Un session bean llevará a cabo su función interactuando con otros session beans y con
entity beans.
En los session beans el desarrollador debe incluir el código de restauración de la información en
memoria.
Existen dos tipos de session beans, aquellos que no tienen estado (stateless) y aquellos que si lo
tienen (statefull).
En los beans stateless no es necesaria ninguna restauración en el momento de abortar una
transacción, pero para los beans statefull si es necesario.
La especificación permite separar lo que se refiere a código de la lógica del negocio del código que
permite restaurar el estado en memoria.
Si un statefull session bean debe sincronizarse con la transacción en la que participa, debe
hacerlo realizando la interfaz javax.ejb.SessionSynchronization.
El método ejbAfterBegin() de esta interfaz permite hacer una copia de la información al comienzo
de la transacción.
Los métodos ejbBeforeCompletion() y ejbAfterCompletion(), reciben un valor de tipo Boolean como
parámetro, indicando si la transacción tuvo éxito o no, podemos restaurar el estado de la memoria
utilizando la copia realizada cuando se invocó el método ejbAfterBegin().

Características de Container Managed Transactions (CMT)


 El contenedor de EJB define los límites de la transacción.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 El código no incluye referencias que delimiten el principio y el final de la transacción
asociada.
 Es el que se utiliza por defecto.
 Normalmente, el contenedor comienza una transacción justo antes del inicio de un método y
realiza un commit justo después del final del método.
 Cada método está asociado a una única transacción.
 No se permiten transacciones múltiples o anidadas dentro de un método (modelo plano)
 No se requiere que todos los métodos estén asociados a la transacción. El desarrollador
indica los métodos asociados mediante atributos de transacción.
 No está permitido utilizar otros métodos de manejo de transacciones asociados con Bean o
Application Managed Transactions.
 Se pude utilizar el método setRollbackOnly de la interfaz EJBContext para forzar un rollback.
 La transacción termina con commit cuando el cliente que inició la transacción termina
normalmente.
 La transacción termina con rollback si se provoca una excepción de sistema o se llama
explícitamente al método setRollbackOnly.
 Si el bean genera una excepción de la aplicación, el rollback no es automático, se debe llamar
al método setRollBackOnly, normalmente dentro de un bloque try-catch.

Los métodos permitidos en CMT son:


 commit, setAutoCommit y rollback de la clase java.sql.Connection.
 getUserTransaction de la clase javax.ejb.EJBContext.
 Todos los métodos de la clase javax.transaction.UserTransaction.

Estos métodos se utilizan con Bean-managed Transactions o con Application-managed Transactions.

Atributos de Transacciones
Los atributos de las transacciones se especifican mediante anotaciones u opcionalmente, en un
deployment descriptor.
Si las anotaciones se especifican a nivel de clase, dichas anotaciones se aplican a todos los métodos
de la clase.
Cada método puede tener sus anotaciones, las cuales substituyen (override) a las de la clase.
Las anotaciones de los atributos son las siguientes:
 Required @TransactionAttribute(REQUIRED)
 RequiresNew @TransactionAttribute(REQUIRES_NEW)
 Mandatory @TransactionAttribute(MANDATORY) Mandatory
@TransactionAttribute(MANDATORY)
 NotSupported @TransactionAttribute(NOT_SUPPORTED)
 Supports @TransactionAttribute(SUPPORTS)
 Never @TransactionAttribute(NEVER)
Required
Por defecto. Si un cliente está corriendo dentro una transacción e invoca un método de un bean, el
método se ejecuta dentro de la misma transacción.
Si el cliente no está asociado con una transacción, el contenedor inicia una nueva antes de ejecutar
el método.
RequiresNew
Si un cliente está corriendo dentro de una transacción e invoca un método, la transacción del cliente
se suspende, se inicia una nueva, la cual se termina al finalizar el método y se reinicia la transacción
del cliente.
Mandatory

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Si el cliente está corriendo dentro una transacción e invoca un método de un bean, el método se
ejecuta dentro de la misma transacción.
Si el cliente no está asociado con una transacción, se genera la excepción
TransactionRequiredException.
NotSupported
Si el cliente está corriendo dentro de una transacción e invoca un método, la transacción del cliente
se suspende, cuando termina el método, la transacción del cliente se reanuda.
Si el cliente no está asociado a una transacción, el contenedor no inicia una nueva.
Supports
Si el cliente está corriendo dentro una transacción e invoca un método de un bean, el método se
ejecuta dentro de la misma transacción.
Si el cliente no está asociado con una transacción, el contenedor no inicia una nueva.
Never
Si el cliente está corriendo dentro de una transacción e invoca un método, el contenedor genera una
excepción de la clase RemoteException.
Si el cliente no está asociado a una transacción, el contenedor no inicia una nueva.
Ejemplo de código de una transacción:
@TransactionAttribute(NOT_SUPPORTED)
@Stateful
public class BeanTransacciones implements Transaction {
...
@TransactionAttribute(REQUIRES_NEW) @TransactionAttribute(REQUIRES_NEW)
public void PrimerMetodo() {...}
@TransactionAttribute(REQUIRED)
public void SegundoMetodo() {...}
public void TercerMetodo() {...}
public void CuartoMetodo() {...}
}

Transacciones JTA
JTA provee un API de alto nivel para el control de transacciones distribuidas. JTA hace de mediador
entre:
El servidor de aplicaciones y el Transaction Manager (TM).
El servidor de aplicaciones utiliza JTA para controlar las transacciones declaradas y para controlar el
enlistamiento de los recursos a las transacciones.
 La aplicación basada en componentes y el TM. Lo usa el desarrollador de los componentes
para marcar las transacciones manualmente.
 Los Resource Manager (RM) y el TM. Provee las interfaces basadas en el protocolo XA
(estándar de X/Open) a implementar por los resource managers a los efectos de ser
enlistados y controlados por el TM.
Un objetivo importante de la especificación J2EE con respecto al manejo transaccional es que sea lo
más simple posible.
El desarrollador de la aplicación basada en componentes solamente debe señalar la
transacción (en forma manual o declarativa), y el resto corre por parte de la infraestructura
subyacente.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El servidor de aplicaciones es responsable de enlistar como parte de la transacción a los recursos
que los distintos componentes van utilizando y en algunos casos, coordinar para que en caso de
rollback el estado de los componentes sea consistente.
JTA (Java Transaction API) es una API que permite delimitar las transacciones de manera
independiente del manejador de transacciones del Application Server.
El SUN Application Server implementa el manejador de transacciones mediante el servicio JTS, Java
Transactions Service, pero el desarrollador no llama a los métodos de bajo nivel de JTS, sino que
invoca métodos de JTA.
Este mecanismo de transacciones no soporta transacciones anidadas, es decir, no se puede iniciar
una transacción hasta que la activa haya terminado.
Para delimitar las transacciones JTA, se utilizan los siguientes métodos de la interfaz
javax.transaction.UserTransaction:
 begin
 commit
 rollback
En los session EJB de tipo stateless, cada método del bean debe terminar con commit o rollback.
En los session EJB de tipo stateful, no existe esta restricción, la demarcación de la transacción se
puede pasar de método a método de manera que sólo un método del bean pudiera invocar el
método begin y otro hacer el commit o rollback.
Ejemplo de un Bean que utiliza BMT para realizar la transacción poniendo como ejemplo una base de
datos de stock cualquiera:
import java.util.*;
import javax.ejb.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import javax.transaction.*;
@Stateless
@TransactionManagement(BEAN)
public class BeanStock implements Stock {
@Resource javax.Transaction.UserTransaction mitransaccion;
@Resource javax.sql.DataSource ds1;
public void updateStock(int idstock, double precio) {
Connection con = null;
PreparedStatement prepStmt = null;
try {
con = ds1.getConnection();
mitransaccion.begin();
prepStmt = con.prepareStatement(
“UPDATE Stock set precio = ? where IdStock = ?”);
prepStmt.setDouble(1, precio);
prepStmt.setInt(2, idstock);
int registrosafectados = prepStmt.executeUpdate();
mitransaccion.commit();
} catch (Exception ex) {
try {
mitransaccion.rollback();
} catch (SystemException ex) {
throw new EJBException (“Rollback ha fallado: “ + ex.getMessage();
}
throw new EJBException(“La transaccion ha fallado: “ + ex.getMessage());
} finally {
try {

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
prepStmt.close();
con.close();
} catch (SQLException ex) {
throw new EJBException (“Error al cerrar la conexion: “ + e.getMessage());
}
}
}

Ver Video: Creación de una transacción en CMT Contenedor de


Transacciones, en la Unidad 9, en el Módulo 4, en la
plataforma elearning

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 10. Desarrollando Aplicaciones Java
usando mensajería

Introducción
La API Java Message Service, servicio de mensajes Java, también conocida por sus siglas JMS, es la
solución creada por Sun Microsystems para el uso de colas de mensajes.
Este es un estándar de mensajería que permite a los componentes de aplicaciones basados en la
plataforma Java2 crear, enviar, recibir y leer mensajes. También hace posible la comunicación
confiable de manera síncrona y asíncrona.
El servicio de mensajería instantánea también es conocido como Middleware Orientado a Mensajes
(MOM por sus siglas en inglés) y es una herramienta universalmente reconocida para la construcción
de aplicaciones empresariales.
Dicha API es parte integral de la versión 2 de Java.
Existen dos modelos de la API JMS, los cuales son:

Modelo Punto a Punto:


Este modelo cuenta con solo dos clientes, uno que envía el mensaje y otro que lo recibe.
Este modelo asegura la llegada del mensaje ya que si el receptor no esta disponible para aceptar el
mensaje o atenderlo, de cualquier forma se le envía el mensaje y este se encola en una pila del tipo
FIFO para luego ser recibido según haya entrado.

Modelo Publicador/Suscriptor
Este modelo cuenta con varios clientes, unos que publican temas o eventos, y los que ven estos
temas, a diferencia del modelo punto a punto este modelo tiende a tener más de un consumidor.
Ambos modelos pueden ser síncronos mediante el método receive y asíncronos por medio de un
MessageListener.
Objetivo
 Conocer la tecnología Java Message Service JMS.
 Comprender el funcionamiento y los tipos de mensajes que podemos implementar dentro de
la plataforma Java EE.

Servicios de mensajería
Los servicios de mensajería permiten la comunicación asíncrona entre diversas aplicaciones.
Dichos servicios de mensajería permiten el uso de relaciones de igual a igual entre componentes de
las aplicaciones manteniendo el grado de anonimato entre los productores y los consumidores de
mensajes.
Un sistema de mensajería debe ser escalable, confiable y fácil de integrar en redes heterogéneas.
Java EE incluye la API Java Message Services para implementar las aplicaciones de mensajería.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Los sistemas de mensajería deben cumplir con una serie de características, independientes a su
plataforma:
 Garantizar que el mensaje se entrega aunque el consumidor no se encuentre disponible o
conectado.
 Permitir que existan elementos transaccionales tanto en el envío como en la recepción de los
mensajes.
 Entregar los mensajes una única vez a cada uno de los destinatarios.
Existen dos tipos de modelos de mensajería:
Punto a punto: Los mensaje se envían a una cola y existe solamente un consumidor para cada
mensaje.

Publicación Suscripción: Los productores de los mensajes los asocian con un destino llamado tópico,
y los consumidores se subscriben a tópicos de su interés. Un ruteador de mensajes se encarga de
realizar la entrega a los diferentes subscriptores.

Los sistemas de mensajería soportan envío de mensajes de forma síncrona y asíncrona.


Cuando utilizamos la forma síncrona, el productor solicita el envío de cada mensaje y el productor
queda bloqueado hasta que el consumidor acepta el mensaje. Aunque JMS se puede utilizar de
forma síncrona, su mayor ventaja es utilizar la forma asíncrona.
En la forma asíncrona, los productores generan los mensajes sin bloquearse, continúan su ejecución
inmediatamente después de enviar el mensaje.

Java Message Service API


JMS es la especificación de Java EE que permite estandarizar el servicio de mensajes en aplicaciones
JEE.
Consta de un conjunto de interfaces que el desarrollador puede asumir que han sido implementadas
por el sistema de mensajería.
Define un conjunto común de conceptos de mensajería y estrategias de programación para el
desarrollo de aplicaciones que utilicen mensajes asíncronos.
JMS es la solución de Sun para los sistemas de mensajes, vamos comenzar por saber que es un
sistema de mensajes empresarial.
En las comunicaciones cliente servidor, los datos que se intercambian entre las dos partes necesitan
de una comunicación síncrona, es decir, que las dos partes estén presentes en el momento de la
comunicación.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Los sistemas de mensajes aportan una serie de mejoras a la comunicación entre aplicaciones que no
tienen por qué residir en la misma máquina.
JMS se sitúa como middleware en medio de la comunicación de dos aplicaciones.
En entornos cliente servidor, cuando la aplicación A necesita comunicarse con la Aplicación B,
necesita saber donde esta B y que B esté escuchando en ese momento.
Cuando se usa JMS (o cualquier otro sistema de mensajes), la aplicación A envía un mensaje, el
sistema de mensajes lo recibe y se lo envía a B cuando se conecte al servicio.
De esta manera se consigue una comunicación asíncrona entre A y B, es decir no hace falta que B
este presente en el momento del envío del mensaje, y no por ello va a dejar de recibirlo.
La comunicación anterior tiene dos extremos, el productor (A) y el consumidor (B).
JMS soporta otro tipo de comunicaciones que Sun denomina Publisher/Subscriber, traducido seria
Publicador/Suscriptor.
En este tipo de comunicación, la aplicación A publica su mensaje en el servicio JMS y lo reciben
todas las aplicaciones que estén suscritas al servicio JMS al que se envió el mensaje, esta forma de
comunicación es exactamente igual que la que se produce el los chats del IRC.
Otra de las ventajas de usar JMS (o cualquier otro sistema de mensajes) es que las aplicaciones se
pueden cambiar simplemente asegurándose que la nueva aplicación entiende los mensajes que se
intercambian.
Existen diversas implementaciones para trabajar con JMS.
Para enviar o recibir mensajes los clientes tienen que conectarse por medio de los objetos
administrados, este nombre lo reciben porque son creados por el administrador (j2eeadmin).
Estos implementan las interfaces JMS y se sitúan en el espacio de nombres JNDI (Java Naming and
Directory Interface) para que así los clientes puedan solicitarlos.

Modelo de programación de JMS


Existen varios objetos administrados en la tecnología JMS para poder realizar el envío de mensajes.
Vamos a analizar sus características.
 ConnectionFactory: Se usa para crear una conexión al proveedor del sistema de mensajes.
 Destination: Son los destinos de los mensajes que se envían y el recipiente de los mensajes
que se reciben.

Mensajes
Son la base de la tecnología JMS, se componen de tres elementos comunes entre todos los tipos que
existen:
 Header: Es la cabecera del mensaje, le sirve a los clientes y a los proveedores para poder
identificarlos.
 Properties: Son propiedades en general para personalizar y/o hacer más especifico un
mensaje.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 Body: Es el mensaje en sí mismo, hay varios tipos de “cuerpos” que puede llevar un
mensaje:

Connection Factories
Son los objetos que utiliza un cliente para crear una conexión a un proveedor de servicios de
mensajería.
Encapsula un conjunto de parámetros de conexión definidos previamente por un administrador.
Por ejemplo:
@Resource(mappedName=”jms/ConnectionFactory”)
private static ConnectionFactory connectionFactory;

Destinations
Son los objetos que utiliza un productor o consumidor para especificar el destino de los mensajes
que produce o la fuente de los mensajes que consume.
En el modelo punto a punto, los destinos se llaman queues y el tipo publicación subscripción se
llaman topics.
Por ejemplo:
@Resource(mappedName=”jms/Queue”)
private static Queue queue;
@Resource(mappedName=”jms/Topic”)
private static Topic topic;

Connections
Son los objetos que encapsulan una conexión virtual con un proveedor JMS.
Se utilizan para crear una o más sesiones.
Implementan la interfaz Connection.
Ejemplo:
Connection conexion = connectionFactory.createConnection();
------
conexion.close();

Sessions
Son los contextos utilizados para producir y consumir mensajes. (single-thread-context).
Se utilizan para crear los siguientes elementos:
 Productores de mensajes
 Consumidores de mensajes.
 Los propios mensajes
 Exploradores de las colas de mensajes (Queue browsers)
 Colas y tópicos temporales

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Los objetos Session dependen de la conexión.
Algunos ejemplos:
Creando una sesión que permite las transacciones:
Session sesion = conexion.createSession(false, Session.AUTO_ACKNOWLEDGE);
Sesión que no utiliza transacciones:
Session sesion = conexion.createSession(true,0);

Productores de mensajes
Son los objetos creados para una sesión y que son utilizados para enviar mensajes a un destino.
Ejemplo:
MessageProducer productor = sesion.createProducer(queue);
MessageProducer productor = sesion.createProducer(topic);
productor.send(message);

Consumidores de mensajes
Son los objetos creados por una sesión y que son utilizados para recibir mensajes por un destino.
Ejemplo:
MessageConsumer consumidor = sesion.createConsumer(queue);
MessageConsumer consumidor = sesion.createConsumer(topic);
Conexión.start();
Para consumir de forma síncrona se utiliza el método receive.
Message mensaje = consumidor.receive(tiempo);
Para consumir mensajes de forma asíncrona es necesario un objeto Message Listener que se
encarge de manejar los eventos.
Lo primero que habría que hacer es registrar el objeto Message Listener:
Listener mylistener = new Listener();
consumidor.setMessageListener(mylistener);
A continuación, debemos llamar al método start de la conexión para iniciar el proceso de la escucha
de los mensajes.
Cuando se recibe un mensaje, se ejecuta el método onMessage del objeto Listener.

Formato de los mensajes


JMS define un formato de mensaje abstracto que puede ser utilizando para trabajar con diversos
formatos existentes.
Contiene un header (cabecera) que puede configurarse con diferentes campos opcionales y un
cuerpo que soporta diversos tipos de datos.
El header debe contener información de identificación y usuario.
El body (cuerpo) contiene los datos de la aplicación.
Gráfico con la estructura de los mensajes:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Con JMS podemos definir cinco tipo de mensajes:
 StreamMessage: Contiene un flujo (stream) de datos que se escriben y leen de manera
secuencial.
 MapMessage: Contiene pares nombre-valor.
 TextMessage: Contiene un String.
 ObjectMessage: Contiene un objeto que implemente la interfaz Serializable.
 BytesMessage: Contiene un stream de bytes.
Existe un sexto tipo de mensaje llamado specialMessage, pero que no contiene body, solamente
headers.
Cada tipo de mensaje contiene una serie de métodos diferentes entre si, por ejemplo con un
mensaje de texto:
TextMessage mensaje = sesion.createTextMessage();
mensaje.setText(“Mi mensaje de texto”);
productor.send(mensaje);

Message Driven Bean


La especificación 2.0 de EJB introdujo un nuevo tipo de Enterprise Java Bean, el Message Driven
Bean.
Hasta dicha versión, para integrar una aplicación J2EE con JMS teníamos que programar un
consumidor de mensajes que hiciese llegar los mensajes que recibiese a un Session Bean, y que
fuese dicho bean el que los tratase.
Esta solución, además de insertar una capa más, no era la solución más correcta. Con la inclusión
del nuevo tipo de EJB, se consigue que la aplicacion J2EE sea capaz de recibir mensajes JMS y de
tratarlos por si misma.
Este nuevo tipo de beans, se comporta como un bean de sesión sin estado.
Los MDB's (Message Driven Beans), al contrario que los otros tipos de EJB, no tienen que
implementar ninguna interfaz remota, pues no van a ser utilizados desde fuera del servidor de
aplicaciones, por lo que solo hace falta programar el Bean propiamente dicho.
Todos los MDB's implementan dos interfaces:
 MessageDrivenBean.

Nos obliga a sobreescribir los métodos:


ejbCreate()
ejbRemove()
setMessageDrivenContext()
 MessageListener: Interfaz ya conocida y sobre la que tenemos que sobreescribir el método
onMessage().

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El enterprise bean se comporta de la misma forma que un cliente normal que recupere mensajes en
el servicio JMS.
La diferencia es que no tenemos que preocuparnos en conseguir las interfaces de la JNDI, pues de
eso ya se encarga el servidor de aplicaciones, nosotros solo le debemos indicar cual será la factory y
el asunto o la cola de la que debe recibir mensajes.
Existen dos tipos de MDBs:
 Message-Driven Beans JMS.

Se debe utilizar la anotación @javax.ejb.MessageDriven.


Implementan la interfaz javax.jms.MessageListener.
El Application Server tiene soporte integrado o puede utilizar un conector.
 Message-Driven Beans NO JMS.

Debemos utilizar la anotación @javax.ejb.MessageDriven


Implementan una interfaz específica del sistema de mensajería.
El Application Server necesita un conector.
Toda clase Message-Driven debe seguir unos puntos:
 Debe utilizar la anotación @MessageDriven
 Debe ser pública
 No puede ser abstracta o final.
 Debe contener un constructor público sin argumentos.
 No debe definir un método finalice
 Solamente si es una Interfaz JMS:
o Implementar la interfaz MessageListener
o Contener el método onMessage().

Elementos de la anotación @MessageDriven:


 mappedName: Nombre de la cola o tópico a procesar
 activationConfig: Lista de propiedades del bean
 messageListenerInterface: Nombre de la interfaz del bean
 name: Nombre opcional del bean
 description: Descripción del bean
Ejemplo de declaración de la anotación:
@MessageDriven(mappedName=”jms/NombreBean”,
activationConfig={@ActivationConfigProperty(propertyName=_
”acknowledgeMode”, propertyValue=”Auto-acknowledge”),
@ActivationConfigProperty(propertyName=”destinationType”,_
propertyValue=”javax.jms.Queue”)})
Especificaciones del método onMessage():
 Cuando el destino JMS (queue o topic) recibe un mensaje, el contenedor de EJB invoca al
método onMessage.
 Debe ser público
 No puede ser abstracto o final
 Recibe un solo argumento: el propio mensaje
 Su responsabilidad es hacer el casting del mensaje y llevar a cabo toda la lógica de negocio.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ver Video: Configuración de mensajes en el servidor, en la
Unidad 10, en el Módulo 4, en la plataforma elearning

Laboratorio: Crear Servicio Mensajería


Objetivos
 Conocer la implementación y el funcionamiento de la tecnología JMS.
 Conocer cómo configurar el servidor para poder admitir servicios de mensajería JMS.
Enunciado
Vamos a realizar una aplicación que enviará mensajes al servidor utilizando la tecnología JMS.
Lo primero de todo será irnos a la pestaña Services dentro del entorno gráfico de NetBeans.

Iniciamos el servidor de aplicaciones con el botón derecho y seleccionando Start.

Una vez iniciado el servidor, debemos irnos a la consola de administración del contenedor para
poder visualizar las características propias de JMS. Para ello, seleccionamos la opción View Admin
Console.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Al entrar en la consola de administración de GlassFish, podremos visualizar que tenemos dos
opciones dentro de Recursos JMS.
Fabricas de Conexión y Recursos de destino.
En este apartado sería dónde podríamos configurar nuestros servicios de mensajería para poder
enviar y recibir mensajes mediante MDB.

Pulsamos sobre Nuevo para poder crearnos un nuevo conector sobre JMS.
Lo llamaremos jms/QueueFactory y debe estar activado.

Cuando pulsemos en guardar, veremos sus características.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora pulsaremos sobre Recursos de destino y nos crearemos uno nuevo.

Llamaremos al JNDI jms/Queue y el nombre de nuestro destino será midestino.


El tipo de recurso será javax.jms.Queue y debe estar activado.

Veremos sus características al guardarlo.

Ahora vamos a probarlo, para ello, nos creamos un nuevo proyecto Enterprise Application.

Llamaremos a la aplicación MiAplicacionMDB y crearemos los proyectos WAR Y EJB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sobre el proyecto WAR nos agregamos un nuevo Servlet.

Lo vamos a llamar GeneradorMensajes y lo incluiremos en un nuevo paquete llamado paquetemdb.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
No agregaremos la información al descriptor de despliegue.

Ahora escribimos la llamada a los recursos del servidor en el servlet escribiendo el siguiente código
dentro de la clase:

@Resource(mappedName="jms/QueueFactory")
javax.jms.QueueConnectionFactory queueConnection;
@Resource(mappedName="jms/Queue")
javax.jms.Queue queue;
Añadimos los import necesarios mediante el entorno NetBeans.

Hacemos un import a la librería import javax.jms.*;


import javax.jms.*;
Implementamos el código de processrequest del servlet:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet GeneradorMensajes</title>");

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
out.println("</head>");
out.println("<body>");
Connection connection=queueConnection.createConnection();
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer=session.createProducer(queue);
MapMessage message=session.createMapMessage();
String nombre = request.getParameter("txtnombre");
String apellido = request.getParameter("txtapellido");
String texto = request.getParameter("txttexto");
message.setString("nombre", nombre);
message.setString("apellido", apellido);
message.setString("texto", texto);
producer.send(message);
producer.close();
session.close();
connection.close();
out.println("<h1>Servlet Generador Mensajes</h1>");
out.println("El mensaje se ha enviado correctamente");
}catch (Exception ex)
{
out.println("<h1>Excepcion al enviar el mensaje</h1>");
out.println(ex.toString());
} finally {
out.println("</body>");
out.println("</HTML>");
out.close();
}
}
Una vez que hemos configurado el servlet para enviar mensajes, es el momento de crearnos un
objeto de la clase Message Driven Bean. Sobre el proyecto EJB agregamos un nuevo objeto
Message-Driven Bean.

Le indicaremos la opción Server Destinations nuestro recurso jms/Queue creado al principio del
laboratio. Lo llamaremos BeanMDB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora implementamos el código del Bean.
package paquetemdb;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
@MessageDriven(mappedName = "jms/Queue", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-
acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue =
"javax.jms.Queue")
})
public class BeanMDB implements MessageListener {
public BeanMDB() {
}
@Override
public void onMessage(Message message) {
System.out.println("Mensajes recibidos en el MDB...");
try {
MapMessage msg = (MapMessage) message;
System.out.println("Nombre:" + msg.getString("nombre"));
System.out.println("Apellido:" + msg.getString("apellido"));
System.out.println("Texto:" + msg.getString("texto"));
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
}
Ya tenemos todo configurado para enviar y consumir mensajes, nos quedaría una parte gráfica para
enviar los mensajes. Para ello, utilizaremos la página index.jsp del proyecto WAR.

Implementamos su código:
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Enviar mensajes a la cola Queue JMS</h1>
<form name="form1" action="GeneradorMensajes">
<table border="1">

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
<tr>
<th>Nombre</th>
<td>
<input type="text" name="txtnombre">
</td>
</tr>
<tr>
<th>Apellidos</th>
<td>
<input type="text" name="txtapellidos">
</td>
</tr>
<tr>
<th>Texto del mensaje</th>
<td>
<textarea name="txttexto" rows="4" cols="20">
</textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Enviar mensaje a la cola">
</td>
</tr>
</table>
</form>
</body>
</HTML>
Solo nos quedaría probar el proyecto.

Como podemos comprobar, el servlet ha enviado el mensaje.

Y hemos mostrado el mensaje en la consola para el consumidor.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 11. Desarrollo del envío de mensajes
Introducción
Los EJB’s contienen un tipo de Beans denominado Message-Driven Beans (MDBs).
Dichos Beans utilizan la lógica de negocio y los servicios que proveen son parecidos a los Beans de
Sesión, con la diferencia de que los MDBs son usados para invocar métodos de forma asincrónica.
Cuando se produce la invocación de un método de un MDB desde un cliente, la llamada no bloquea
el código del cliente y el mismo puede seguir con su ejecución, sin tener que esperar
indefinidamente por la respuesta del servidor.
Los MDBs encapsulan el popular servicio de mensajería de Java, JMS.
Los MDBs procesan lógica de negocio, pero un cliente nunca invoca a un método de un MDB
directamente.
El sistema de mensajería asincrónica propone la utilización de una capa intermedia en la
comunicación entre el productor y el consumidor del mensaje.
En EJB 3.0, esta capa se llama MOM (Message-oriented-Middleware).
Principalmente, la MOM es un software que permite funcionar como servidor de mensajería,
reteniendo los mensajes del productor y enviándolos posteriormente al consumidor en el momento
en que esté disponible para recibirlo.

Objetivos
 Conocer la implementación para el envío de mensajes mediante la tecnología Java EE.
 Conocer el funcionamiento de los interceptores para controlar el acceso a los Beans.

Interceptores
Los interceptores, interceptan la llamada a un objeto o método dentro de un entorno Java EE.
Se trata de clases con métodos que pueden ser o no invocadas.
De ser invocadas esto se realiza después de la llamada a un objeto EJB o un método dentro de un
EJB.
Gracias a esto podemos ejecutar código que puede preparar un entorno de ejecución de un método,
y preguntar si se cumplen las condiciones para su ejecución, o es preferible que se invoque una
excepción en lugar de ejecutar el método.
Sus ventajas principales son:
 Permiten al desarrollador un mayor control sobre el flujo de sus programas.
 Se llaman antes y después de la invocación a un método.
 Se aplican a todos los métodos de negocio de un EJB.
 Permiten modificar valores de entrada a métodos.
 Permiten modificar valores de retorno.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 Gestionar las excepciones.
 Interrumpir llamadas completamente.
 Realizar análisis y optimización de métodos.
 Influencias de AOP (es una de las forma de implementar un desarrollo AOP).
Mediante la anotación @Interceptors en una clase, podemos hacer que dicha clase sea la encargada
de interceptar la llamada.
Esa anotación se puede usar a nivel de método o de clase según convenga, y puede declarar a
varios interceptores como si fueran parámetros para que sean ejecutados en orden.

Tipos de Interceptores
Todos los interceptores pueden interceptar el ciclo de vida de un bean.
También se puede definir un método interceptor en el propio Bean, llamado interceptor interno,
mediante la anotación @aroundInvoke.
Los interceptores (externos) se pueden dividir en tres tipos:
 Default (interceptor por defecto)
 Class-level (interceptor de clase)
 Method-level (interceptor de método)

Existe la posibilidad de declarar interceptores globales (default interceptor) que se ejecutan para
todos los métodos de todos los beans.
No se pueden especificar con anotaciones, se necesita editar el descriptor de la aplicación, pero
resultan muy útiles para determinadas tareas.
Podemos utilizar interceptores escribiendo en el fichero ejb-jar.xml:
<ejb-jar ...>
...
<interceptors>
<interceptor>
<interceptor-class>
MiInterceptor
</interceptor-class>
<around-invoke>
<method-name>interceptar</method-name>
</around-invoke>
</interceptor>
<interceptors>
...
<assembly-descriptor>
<!—Interceptor por Defecto, será aplicado a todo metodo de todo bean desplegado-->
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>
MiInterceptor
</interceptor-class>
</interceptor-binding>
...
</assembly-descriptor>
...
</ejb-jar>
Y la clase Interceptora será:
package paquetebean;
import javax.ejb.AroundInvoke;
import javax.ejb.InvocationContext;

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
public class MiInterceptor {
@AroundInvoke
public Object interceptar (InvocationContext ctx) throws Exception {
System.out.println("Interceptor por defecto… " + ctx.getMethod().getName());
try {
return ctx.proceed();
}finally {
System.out.println("Saliendo del interceptor por defecto");
}
}
}
Los interceptores a nivel de clase, interceptan todos los métodos de negocio de EJB donde se
registran.
La anotación Interceptors, también puede definir un array de interceptores de clase. Puede
configurarse con anotaciones o en el fichero ejb-jar.xml
Vamos a ver un ejemplo de interceptor de clase:
@Stateless
@Interceptors ({ClaseInterceptor2.class, ClaseInterceptor1.class})
public class EmailBean {
...
}
Los interceptores a nivel de método, interceptan el método de negocio anotado con Interceptors de
un bean.
Vamos a ver un ejemplo de interceptor de método:
package paquetebean;
import javax.interceptor.Interceptors;
import paqueteinterceptores.MiInterceptor;
@Stateless
public class EmailBean {
...
@Interceptors({MiInterceptor.class})
public void enviarMensaje(string textomensaje)
{
...
}
...
}
Otra faceta de los interceptores es su capacidad de interceptar las llamadas de cambio de estado
(PostConstruct, PreDestroy, PrePassivate, PostActivate).
Para ello debemos declarar un interceptor, en lugar de usar la anotación @AroundInvoke usan
@PreDestroy, @PostConstruct, @PrePassivate o @PostActivate.
Se puede indicar por parte de un bean, que se excluyan los interceptores por defecto para toda la
clase.
También se puede indicar que para un método de un bean, se excluya de la intercepción de los
interceptares por defecto y de clase.
Para obtener este comportamiento podemos utilizar tanto anotaciones como el fichero descriptor de
EJBs.
@ExcludeDefaultInterceptors
public class EmailMDB implements MessageListener {
...
}

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
O bien a nivel de métodos:
public class EmailMDB implements MessageListener {
...
@ExcludeClassInterceptors
@ExcludeDefaultInterceptors
public void enviarMensaje() {
System.out.println("Metodo de negocio de un Bean MDB");
}
...
}
Los interceptores es una tecnología muy útil para los EJB de tipo Message Driven Beans, debido a
que el contenedor es el administrador del envío del mensaje.
De esta forma, tenemos control sobre el acceso a nuestros envíos y recepciones de mensajes
mediante clases Middleware para controlar las características u opciones que deseamos controlar por
parte de la lógica de negocio.
La mayor ventaja que aportan es la capa de acceso intermedio entre el contenedor de mensajes y la
lógica de negocio.

Implementación de los mensajes en Beans MDB


Los beans controlados por mensaje fueron introducidos en la especificación EJB en la versión 2.0,
el objetivo era proporcionar un mecanismo para el manejo asíncrono de mensajes en EJB.
El bean controlado por mensaje es, esencialmente, un oyente de mensajes que puede consumir
mensajes de una cola o de una suscripción a través del contenedor J2EE.
El contenedor invoca al bean como resultado de la llegada de un mensaje JMS.
El cliente percibe el bean controlado por mensajes como un consumidor JMS que implementa la
lógica de empresa, pero que solo puede comunicar con el bean enviándole un mensaje a través de
JMS.
Los beans controlados por mensaje pueden comunicar con beans de sesión y con beans de entidad
para ampliar la lógica de empresa o para proporcionar cierta forma de persistencia de aplicación.
El contenedor EJB realiza las funciones de reserva de recursos, seguridad y gestión de
transacciones, y mantiene el ciclo de vida de los beans controlados por mensaje.
Los beans controlados por mensaje no son ideales para situaciones que requieren que múltiples
colas o apartados sean atendidos por un único consumidor JMS.
Los beans controlados por mensaje deben implementar javax.jms.MessageListener.
El cuerpo del receptor es implementado en el método onMessage() del MessageListener.
Este no debe generar excepciones JMS o de aplicación, en su lugar, las excepciones deben ser
capturadas y, preferiblemente, procesadas. Para ello, podemos utilizar Interceptores que capturen
los posibles errores lógicos de la aplicación.
El EJB controlado por mensaje se inicia con la invocación de los siguientes métodos:
1) newInstance()
2) setMessageDrivenContext(MessageDrivenContext contexto)
3) ejbCreate()

En este punto, hay una instancia MDB en la reserva preparada para métodos del contenedor,
preparada para procesar mensajes desde su destino.
El contenedor invoca ejbRemove() cuando ha finalizado con el EJB.
Hay dos tipos de gestión de transacciones para beans controlados por mensaje:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 Gestionadas por el Bean
 Gestionadas por el contenedor

Transacciones gestionadas por el propio bean


Los limites transaccionales deben ser definidos en el metodo omessage() y realizados o anulados
antes de que devuelva un valor.
La entrega del mensaje no está garantizada porque el proceso de cola esta fuera de los límites
transaccionales, a menos que se utilice j avax.transaction.userTransaction, dónde un cliente puede
manejar la transacción.

Transacciones gestionadas por el contenedor


Este tipo de transacción garantiza la entrega del mensaje.
Solo están permitidos dos atributos transaccionales, NotSupported y Required.
Los beans controlados por mensaje no propagan transacciones distribuidas.
En el caso de NotSupported, el bean es ejecutado sin una transacción.
Si se configura Required, el bean es ejecutado en una nueva transacción.
El funcionamiento de un Bean dirigido por mensajes sería el siguiente:

1) El cliente envía un mensaje a un servicio de mensajería JMS


2) El servicio de mensajería envía el mensaje al contenedor
3) El contenedor obtiene un bean dirigido por mensajes de la reserva de beans
4) El contenedor envía el mensaje al bean mediante una llamada al método onMessage().

Contenedor de JMS
El contenedor de JMS es el encargado de realizar la comunicación entre los mensajes enviados y la
recepción de los mensajes por parte de los consumidores.
El contenedor EJB envuelve una serie de servicios proporcionando una capa de administración para
los componentes.
Los servicios más importantes para el contenedor EJB son los siguientes:
 Manejo de transacciones: apertura y cierre de transacciones asociadas a las llamadas a los
métodos del bean.
 Seguridad: comprobación de permisos de acceso a los métodos del bean.
 Concurrencia: llamada simultánea a un mismo bean desde múltiples clientes.
 Servicios de red: comunicación entre el cliente y el bean en máquinas distintas.
 Gestión de recursos: gestión automática de múltiples recursos, como colas de mensajes,
bases de datos o fuentes de datos en aplicaciones heredadas que no han sido traducidas a
nuevos lenguajes/entornos y siguen usándose en la empresa.
 Persistencia: sincronización entre los datos del bean y tablas de una base de datos.
 Gestión de mensajes: manejo de Java Message Service (JMS).
 Escalabilidad: posibilidad de constituir clusters de servidores de aplicaciones con múltiples
hosts para poder dar respuesta a aumentos repentinos de carga de la aplicación con sólo
añadir hosts adicionales.
 Adaptación en tiempo de despliegue: posibilidad de modificación de todas estas
características en el momento del despliegue del bean.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Para administrar el servicio de mensajería dentro del IDE NetBeans, tenemos el contenedor del
servidor de Glassfish Server.
Vamos a visualizar las características que contiene.
Lo primero de todo será irnos a la pestaña Services dentro del entorno gráfico de NetBeans.

Iniciamos el servidor de aplicaciones con el botón derecho y seleccionando Start.

Una vez iniciado el servidor, debemos irnos a la consola de administración del contenedor para
poder visualizar las características propias de JMS. Para ello, seleccionamos la opción View Admin
Console.

Al entrar en la consola de administración de GlassFish, podremos visualizar que tenemos dos


opciones dentro de Recursos JMS.
Fabricas de Conexión y Recursos de destino.
En este apartado sería dónde podríamos configurar nuestros servicios de mensajería para poder
enviar y recibir mensajes mediante MDB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ver Video: Mensajes de acciones MDB, en la Unidad 11, en el
Módulo 4, en la plataforma elearning

Laboratorio: Crear Servicio Mensajería


Objetivos
 Conocer la implementación y el funcionamiento de la tecnología JMS.
 Conocer cómo configurar el servidor para poder admitir servicios de mensajería JMS.

Enunciado
Vamos a realizar una aplicación que enviará mensajes al servidor utilizando la tecnología JMS.
Lo primero de todo será irnos a la pestaña Services dentro del entorno gráfico de NetBeans.

Iniciamos el servidor de aplicaciones con el botón derecho y seleccionando Start.

Una vez iniciado el servidor, debemos irnos a la consola de administración del contenedor para
poder visualizar las características propias de JMS. Para ello, seleccionamos la opción View Admin
Console.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Al entrar en la consola de administración de GlassFish, podremos visualizar que tenemos dos
opciones dentro de Recursos JMS.
Fabricas de Conexión y Recursos de destino.
En este apartado sería dónde podríamos configurar nuestros servicios de mensajería para poder
enviar y recibir mensajes mediante MDB.

Pulsamos sobre Nuevo para poder crearnos un nuevo conector sobre JMS.
Lo llamaremos jms/QueueFactory y debe estar activado.

Cuando pulsemos en guardar, veremos sus características.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora pulsaremos sobre Recursos de destino y nos crearemos uno nuevo.

Llamaremos al JNDI jms/Queue y el nombre de nuestro destino será midestino.


El tipo de recurso será javax.jms.Queue y debe estar activado.

Veremos sus características al guardarlo.

Ahora vamos a probarlo, para ello, nos creamos un nuevo proyecto Enterprise Application.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Llamaremos a la aplicación MiAplicacionMDB y crearemos los proyectos WAR Y EJB.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Sobre el proyecto WAR nos agregamos un nuevo Servlet.

Lo vamos a llamar GeneradorMensajes y lo incluiremos en un nuevo paquete llamado paquetemdb.

No agregaremos la información al descriptor de despliegue.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora escribimos la llamada a los recursos del servidor en el servlet escribiendo el siguiente código
dentro de la clase:

@Resource(mappedName="jms/QueueFactory")
javax.jms.QueueConnectionFactory queueConnection;
@Resource(mappedName="jms/Queue")
javax.jms.Queue queue;
Añadimos los import necesarios mediante el entorno NetBeans.

Hacemos un import a la librería import javax.jms.*;


import javax.jms.*;
Implementamos el código de processrequest del servlet:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet GeneradorMensajes</title>");
out.println("</head>");
out.println("<body>");
Connection connection=queueConnection.createConnection();
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer=session.createProducer(queue);
MapMessage message=session.createMapMessage();
String nombre = request.getParameter("txtnombre");
String apellido = request.getParameter("txtapellido");
String texto = request.getParameter("txttexto");
message.setString("nombre", nombre);

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
message.setString("apellido", apellido);
message.setString("texto", texto);
producer.send(message);
producer.close();
session.close();
connection.close();
out.println("<h1>Servlet Generador Mensajes</h1>");
out.println("El mensaje se ha enviado correctamente");
}catch (Exception ex)
{
out.println("<h1>Excepcion al enviar el mensaje</h1>");
out.println(ex.toString());
} finally {
out.println("</body>");
out.println("</HTML>");
out.close();
}
}
Una vez que hemos configurado el servlet para enviar mensajes, es el momento de crearnos un
objeto de la clase Message Driven Bean. Sobre el proyecto EJB agregamos un nuevo objeto
Message-Driven Bean.

Le indicaremos la opción Server Destinations nuestro recurso jms/Queue creado al principio del
laboratio. Lo llamaremos BeanMDB.

Ahora implementamos el código del Bean.


package paquetemdb;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
@MessageDriven(mappedName = "jms/Queue", activationConfig = {

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-
acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue =
"javax.jms.Queue")
})
public class BeanMDB implements MessageListener {
public BeanMDB() {
}
@Override
public void onMessage(Message message) {
System.out.println("Mensajes recibidos en el MDB...");
try {
MapMessage msg = (MapMessage) message;
System.out.println("Nombre:" + msg.getString("nombre"));
System.out.println("Apellido:" + msg.getString("apellido"));
System.out.println("Texto:" + msg.getString("texto"));
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
}
Ya tenemos todo configurado para enviar y consumir mensajes, nos quedaría una parte gráfica para
enviar los mensajes. Para ello, utilizaremos la página index.jsp del proyecto WAR.

Implementamos su código:
<%@page contentType="text/HTML" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Enviar mensajes a la cola Queue JMS</h1>
<form name="form1" action="GeneradorMensajes">
<table border="1">
<tr>
<th>Nombre</th>
<td>
<input type="text" name="txtnombre">
</td>
</tr>
<tr>
<th>Apellidos</th>
<td>
<input type="text" name="txtapellidos">

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
</td>
</tr>
<tr>
<th>Texto del mensaje</th>
<td>
<textarea name="txttexto" rows="4" cols="20">
</textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Enviar mensaje a la cola">
</td>
</tr>
</table>
</form>
</body>
</HTML>
Solo nos quedaría probar el proyecto.

Como podemos comprobar, el servlet ha enviado el mensaje.

Y hemos mostrado el mensaje en la consola para el consumidor.

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 12. Modelo de los servicios Web

Introducción
Los servicios web son una revolución informática en la nueva generación de aplicaciones que
trabajan relacionalmente entre diferentes servidores y entre diferentes lenguajes.
La informática se inicio con programas monousuarios implantados en grandes ordenadores.
Posteriormente, estas primeras aplicaciones alcanzaron la capacidad de atender a diferentes
usuarios.
Pasaron los años y llegó la arquitectura cliente-servidor conocida hasta hoy, que gracias a este
modelo de desarrollo, la aplicación se dividía en una parte que interaccionaba con el usuario y otra
parte destinada al procesamiento de información.
En este paso, se consiguió que cada una de las partes que integraban la aplicación pudiera residir en
ordenadores diferentes.
Con el paso del tiempo, la complejidad de las aplicaciones aumentó y llegó la era de las aplicaciones
distribuidas, en las cuales los procesos se realizaban en diferentes unidades.
Como punto final a esta implementación de las aplicaciones, los servicios web son un paso más allá
en la informática de desarrollo de aplicaciones distribuidas.
Los servicios web permiten distribuir aplicaciones mediante protocolos que son reconocidas por los
clientes independientemente de su lenguaje, es decir, puedo leer métodos y acciones realizadas en
otros lenguajes desde la plataforma de Java y a la inversa.
Objetivo
 Comprender el funcionamiento de los servicios Web y su utilidad dentro de la tecnología Java
EE.
 Conocer los conceptos de SOAP y creación de respuestas por parte del servidor en el acceso
a los servicios web.

Estructura de los servicios Web


La estructura de cualquier servicio web incluye cinco elementos básicos para su desarrollo completo:
 UDDI
 WSDL
 SOAP
 XML
 Transporte

UDDI

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
El UDDI sirve para la publicación y localización de servicios.
Sus siglas significan Universal, Description, Discovery and Integration.
La descripción de los servicios (documentos WSDL) se almacena en un directorio de servicios UDDI
especificado.
Dicho servicio UDDIespecífica como se publican y descubren los servicios, y como trabajan los
directorios de servicios Web.
Para obtener acceso al directorio UDDI mediante Servicios Web se utilizan los SOAP.
El servidor da de alta los servicios (documentos WSDL + descripción)
El cliente “descubre” servicios (documentos WSDL) en el UDDI.

SOAP
SOAP: Simple Object Access Protocol
Su objetivo es especificar como organizar la información de forma estructurada y tipada usando XML
para que sea intercambiada entre los extremos de la invocación del servicio.
El protocolo soap está especificado por el W3C.
http://www.w3.org/2000/xp/Group/
El protocolo SOAP especifica las siguientes reglas:
Formato de mensajes común y extensible.
Describe como se organiza en forma de documentos XML la información a intercambiar.
Es un conjunto de normas para implementar RPC mediante mensajes SOAP.
Son las reglas a seguir por las entidades (cliente o servidor) que procesen los mensajes SOAP.
Indica los elementos a tratar u omitir, quién debe hacerlo y los tipos de acciones a realizar.
Descripción del modo en que se enviarán los mensajes SOAP sobre el protocolo de transporte (HTTP
o SMTP).
Características más importantes
SOAP define un intercambio de mensajes sin estado.
Posibilidad de soportar comunicaciones con estado añadiendo información adicional (IDs ´unicos) en
la cabecera de los mensajes SOAP.
Define una comunicación en una sola dirección
Las interacciones más complejas son gestionadas por los extremos o endpoints.
Esquemas síncronos (RPC): mensaje petición + mensaje respuesta.
Esquemas asíncronos: solamente mensaje petición
SOAP no impone restricciones sobre la semántica de los mensajes intercambiados.
SOAP solo ofrece la infraestructura para transferir esos mensajes.
El significado de los mensajes (etiquetas XML) es interpretado por los extremos endpoints.
SOAP es independiente del modelo de datos de la aplicación.
SOAP no se encarga de cuestiones de fiabilidad, integridad de los mensajes, transacciones,
seguridad, etc. La gestión de esos elementos es responsabilidad de la infraestructura de la
aplicación que implementa el Servicio Web.
El extremo contará con un servidor Web que recibirá la petición SOAP y la redirigirá a la
implementación del servicio Web.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
La implementación real del Servicio Web puede residir en un CGI (Common Gateway Interface), un
Servlet, un Componente EJB (Enterprise Java Bean), etc.

WSDL
Es la descripción de los servicios y lo que se incluyen en ellos para ser enviados al cliente que
consuma dichos servicios web.
WSDL: Web Services Description Language.
Es una capa Middleware entre el servicio web y el consumo de los servicios por parte del cliente.
Se utilizan interfaces para definir los contratos que serán expuestos en el servicio y consumidos por
el cliente.
Los servicios web necesitan una descripción de interfaces independiente de la plataforma.
La información que debe contener el formato de WSDL es la siguiente:
1) Definición de operaciones: nombre, argumentos (nombre + tipo) y el valor retorno de
métodos.
2) Definición de mecanismos de interacción con el cliente (bindings).
Los sistemas distribuidos convencionales usan siempre el mismo middleware.
En los servicios web, cada servicio se puede servir con distintos protocolos (HTTP, SMTP).

Modelo de Servicios Web


Un Servicio Web es un componente de software con las siguientes características:
 Es accesible a través del interface SOAP (Simple Object Access Protocol).
 Su interface se describe en un documento WSDL (Web Service Description Language).

SOAP es un protocolo de mensajería XML extensible que forma la base de los Servicios Web.
SOAP proporciona un mecanismo simple y consistente que permite a una aplicación enviar mensajes
XML a otra aplicación.
Un mensaje SOAP es una transmisión de una vía desde un emisor SOAP a un receptor SOAP, y
cualquier aplicación puede participar en este intercambio como emisor o receptor.
Los mensajes SOAP se pueden combinar para soportar muchos comportamientos de comunicación,
incluyendo, solicitud/respuesta, respuesta solicitada, mensajería asíncrona de una vía, o incluso
notificación.
SOAP es un protocolo de alto nivel que sólo define la estructura del mensaje y unas pocas reglas
para su procesamiento.
Es completamente independiente del protocolo de transporte subyacente, por eso los mensajes
SOAP se pueden intercambiar sobre HTTP, JMS o protocolos de transporte de e-mail.
En la actualidad, el protocolo HTTP es el más utilizado para los mensajes HTTP.
WSDL es un documento XML que contiene un conjunto de definiciones que describen un Servicio
Web.
Proporciona toda la información necesaria para acceder y utilizar un Servicio Web.
Un documento WSDL describe qué hace el Servicio Web, cómo se comunica, y dónde reside.
Usamos el documento WSDL en el momento del despliegue para crear nuestros interfaces de
servicio.
Algunas implementaciones SOAP también usan WSDL durante la ejecución para soportar
comunicaciones dinámicas.
Tipos de comunicación entre aplicaciones en Web Services:

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 Protocolo de Transporte:
o HTTP/HTTPS
 Codificación de datos
o Protocolo SOAP (Simple Object Access Protocol) y Esquema XML (DTD/XSD)
 Descripción de interfaces o puntos de acceso a aplicación
o WSDL (Web Services Description Language)
 Descripción de servicio y descubrimiento
o UDDI (Universal Description, Discovery and Integration)
 Seguridad
o WS-Security, XML Signature y XML Encription (Especificaciones JSR)

Las APIs de Java para los Web Services son las siguientes:
 JDOM
 JAXP: Java API for XML processing
 JAXB: Java API for XML binding
 JAX-RPC: Java API for RPC
 JAXR: Java API for UDDI registry
 SAAJ: SOAP API with Attachements
 JAX-WS: Java API for WebServices
o API de más alto nivel
o Usa todas las demás por debajo
o Permite manejo de WS sin conocimientos de XML, SOAP, etc

Servicios JAX-RS
API de Java que define una infraestructura (clases e interfaces) para implementar una arquitectura
REST (paquete javax.ws.rs).
Vamos a visualizar primer que es una arquitectura REST:
REST (Representational State Transfer): Se define como un "estilo arquitectónico" para el desarrollo
de aplicaciones distribuidas.
Características de REST:
 Forma de construir aplicaciones distribuidas.
 Centrada en el concepto de RECURSO
 Mecanismos RPC centrados en concepto de operación
 El estado de los recursos reside en el servidor
 Los clientes acceden al estado de recurso mediante REPRESENTACIONES del mismo
transferidas desde el servidor o desde el cliente empleando el protocolo HTTP como
mecanismo de transporte (podrían emplearse otros, REST no es específico de un protocolo)
 Cada aplicación puede utilizar diferentes formatos para la representación de los recursos
o HTML para navegadores web
o XML, JSON para aplicaciones

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
o Con el parámetro Content-Type de las cabeceras HTTP se especifica el tipo MIME de
los datos intercambiados (text/HTML, application/xml, application/json)
o El cliente puede informar al servidor del tipo de representación que necesita
(parámetro Accept en cabecera de las peticiones HTTP)

 Los recursos son identificados y están accesibles mediante uno o varios URI (Uniform
Resource Identifier).
 Incluye un conjunto de anotaciones para especificar el mapeo entre las URIs de los recursos
y los métodos HTTP con los métodos Java de una clase de implementación (endpoint)
 Gestiona automáticamente las representaciones de los recursos intercambiados.
 Emplea JAXB para el tipo MIME application/xml
 Emplea la librería BadgerFish para mapeo de XML a JSON en el caso del tipo MIME
application/json
 La generación y tratamiento de otros tipos de representaciones debe manejarse
manualmente (imágenes, PDF, ...) implementando las interfaces
javax.ws.rs.ext.MessageBodyReader, javax.ws.rs.ext.MessageBodyWriter en una clase
anotada con @jax.ws.rs.ext.Provider.
ANOTACIONES JAX-RS
@Path
La clase de implementación de los recursos REST (resource class) debe señalarse con una anotación
@Path, especificando el path de alto nivel dentro del que se enmarcan las URIs gestionadas por la
clase de implementación (context root).
Pueden anotarse clases Java "normales" o EJBs sin estado.
En el caso de anotar clases "normales" se deberá especificar en el web.xml de la aplicación web el
uso del Servlet de JAX-RS.
En los métodos de dicha clase se puede especificar el path (dentro del path de la clase de
implementación) al que se vinculan los métodos Java.
Podemos asociar nombres a los distintos fragmentos que componen el path, dichos nombres irán
señalados entre los signos {...}.
Podemos especificar los fragmentos del path empleando expresiones regulares.
Anotaciones de métodos http
Especifican el método HTTP al que se vinculan los métodos Java anotados para compatibilidad con
los servicios web JAX-RS.
@GET
Vincula al método anotado las peticiones HTTP GET dirigidas al path correspondiente a ese método.
@PUT
Vincula al método anotado las peticiones HTTP PUT dirigidas al path correspondiente a ese método.
@DELETE
Vincula al método anotado las peticiones HTTP DELETE dirigidas al path correspondiente a ese
método.
@POST
Vincula al método anotado las peticiones HTTP POST dirigidas al path correspondiente a ese método.
Existe otro tipo de servicios web en java que son JAVA-WS y que describiremos en módulos
posteriores.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ver Video: Creación de un Web Service, en la Unidad 12, en el
Módulo 4, en la plataforma elearning

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 13. Implementación de Servicios
Java EE Web Services con JAX-WS
Introducción
Un servicio es un procedimiento, un método o un objeto con una interfaz estable y pública que
puede ser invocado por un cliente.
Los Servicios Web amplían esa idea para permitir que esa invocación pueda realizarse a través de
internet, empleando protocolos Web estándar ya existentes.
Utilizan la arquitectura Orientada a Servicios (SOA)
Es una aproximación al diseño de aplicaciones complejas basada en:
 La identificación de los servicios que ofrecerá.
 La definición de esos servicios
 La organización de las interacciones entre esos servicios
 Importancia de las interfaces
 Descripción de las interfaces
 Tratamiento automático para generar código de implementación de las interfaces mediante
clases.
La idea base de cualquier servicio web será desarrollar el sistema a partir de las interfaces.
La información de los servicios comprende un esquema basado en soap y un resultado.
Dicha información utiliza el lenguaje XML para expresar los elementos de los que está compuesto el
servicio y los datos que devolverá como respuesta a un consumidor de dicho servicio.
Objetivo
 Conocer el funcionamiento de los servicios web utilizando JAVA-WS.
 Consumir servicios web desde clientes y comprobar sus características de comunicación.

Servicios JAX-WS
API de Java EE para la publicación y acceso a servicios web basados en WSDL y SOAP.
Es la implementación por defecto que se incluye en Java SE 6
La gestión de los documentos XML incluidos en las peticiones y respuestas SOAP se delegan en
JAXB.
JAX-WS define su propio conjunto de anotaciones para definir las clases y métodos que actúan como
puntos finales de los mensajes que conforman las invocaciones SOAP para especificar la definición
del fichero WSDL y del binding SOAP.
La implementación del servicio web puede desplegarse empleando un Servlet como endpoint o un
EJB endpoint.
En contenedores que soporten Java EE 6 el despliegue es automático en ambos casos. Al iniciar la
aplicación el contenedor inspecciona las clases en busca de las anotaciones @WebService y
establece los mapeos de URL pertinentes.
En contenedores que no son Java EE 6, debe configurarse en el descriptor de despliegue de la
aplicación (WEB-INF/web.xml) y en el servlet de "escucha" del API JAX-WS.
Definición de servicios web con JAX-WS
El único requisito es contar con un interfaz y/o una clase de implementación anotado con
@WebService.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
En el caso de EJB endpoints, además deben de estar anotados como @Stateless (los servicios web
son sin estado).
La clase de implementación debe ser pública y no puede ser final ni abstract.
La clase de implementación debe contar con un constructor vacío.
La clase de implementación no puede definir un método finalice().
Debe garantizarse una implementación sin estado.
La clase de implementación no puede guardar información de estado entre llamadas del cliente.
Por defecto, para la clase/interface de implementación se generará un elemento WSDL service con el
mismo nombre de la clase y el sufijo Service, además se generará un elemento WSDL portType con
el nombre de la clase.
Para cada método público de la clase se generará un elemento WSDL operation con el mismo
nombre del método y dos elementos WSDL message, uno para la petición (con el nombre del
método) y otro para la respuesta (añadiendo al nombre del método el sufijo respose).
Los parámetros y valores de devolución deben de ser tipos básicos Java, clases anotadas con JAXB,
arrays, Map, List o Collection de los anteriores.
Tipos de Anotaciones JAX-WS
Anotaciones que definen el mapeo WSDL (modifican el comportamiento por defecto):
@WebService:
Señala una clase o interfaz como endpoint de un servicio web.
Incluye atributos para modificar el nombre del elemento service, portType, el name space, etc
(name, targetNamespace, serviceName, portName, wsdlLocation, endpointInterface)
@WebMethod
Permite modificar la definición de las operaciones WSDL (atributo operationName) o excluir métodos
de la clase que no se desean exponer como operaciones del web service (con el atributo
exclude=true).
@WebResult
Permite controlar el nombre del elemento message de WSDL que contendrá el valor de retorno
(atributo name).
@WebParam
Permite configurar los elementos parameter de WSDL vinculados a los parámetros de una operación
(atributos: name, mode [IN, OU, INOUT], targetNamespace, header, partName)
@OneWay
Permite indicar que un método no tendrá valor de retorno.
Existen también anotaciones que definen el binding SOAP de las operaciones y los métodos:
@SOAPBinding
Para un método de la clase endpoint especifica el estilo de codificación de los mensajes (RPC vs.
document) y el tipo de codificación de los parámetros a usar (encoded vs.literal).
Atributos: style, use, parameterStyle.
@SOAPMessageHandler
Especifica detalles de la gestión de los mensajes (petición y respuesta).
Atributos: name, className, initParams, roles, heards
Vamos a visualizar un ejemplo para la creación de un servicio web básico.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Mostraremos una lógica en la que recibiremos una fecha (String) desde el cliente y le enviaremos el
día de la semana a la que corresponde dicha fecha.
Comenzaremos creándonos un nuevo proyecto Web Application.

Lo llamaremos AplicacionWebServices.

Vamos a utilizar el servidor GlassFish, que como hemos leído en la documentación, utiliza servicios
web JAX-WS.
No seleccionaremos ningún framework añadido para la aplicación.

A continuación, agregaremos un nuevo objeto sobre el proyecto.


Sobre la carpeta de Web Services, seleccionamos un objeto Web Service.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Lo llamaremos PrimerWebService y lo incluiremos en un paquete llamado paqueteservicios.
Indicaremos la opción Web Service from Scratch, lo que quiere decir que generaremos el Web
Service en una clase y no en un EJB Stateless.

Como vemos, ya ha incluido la anotación @WebService indicando el tipo de clase que hemos
generado.
Nos marcará un error debido a que tenemos que incluir un método o varios de operación para el
servicio.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Podemos incluir operaciones de dos formas diferentes, desde el código pulsando sobre la ayuda de
la izquierda del código o sobre el designer del servicio web.

Vista desde el diseñador del servicio (pestaña Design)

Al seleccionar Add Operation, nos mostrará una nueva ventana en la que realizaremos la cabecera
del método web service e incluiremos parámetros si los necesitáramos.
Llamaremos a nuestro método GetDiaNacimiento y le indicaremos que recibirá un parámetro de la
clase String llamado fecha.

Una vez que pulsamos sobre OK, veremos en el diseñador el método de forma gráfica.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Y podremos comprobar que hemos añadido un método con anotaciones sobre el servicio en nuestro
código.

Estas son las anotaciones que hemos utilizado para el servicio web:
@WebService identifica a la clase como un servicio Web.
Al incluir este descriptor en la clase el editor del netbeans nos avisa que debemos importa la clase
javax.jws.Webservice.
@WebMethod identifica a una operación como parte del servicio web.
Al igual que con WebService se debe importar la clase WebMethod de mismo paquete.
@WebParam asigna un nombre a los parámetros de una operación.
Son opcionales pero conviene utilizarlos para que el descriptor de nuestro servicio Web sea legible
para los programadores.
Implementamos el código del Web Service para devolver el día a partir de una fecha:
package paqueteservicios;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.jws.WebService;
import java.util.*;
import javax.jws.WebMethod;
import javax.jws.WebParam;

@WebService()
public class PrimerWebService {

@WebMethod(operationName = "getDiaNacimiento")
public String getDiaNacimiento(@WebParam(name = "fecha")
String fecha) throws ParseException {
Date date;

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Calendar calendario = GregorianCalendar.getInstance();
SimpleDateFormat formatoDeFecha = new SimpleDateFormat("dd/MM/yyyy");
date = formatoDeFecha.parse(fecha);
calendario.setTime(date);
int dia, mes, anyo;
int op1, op2, op3, op4, op5, op6, resultado;
dia = calendario.get(Calendar.DAY_OF_MONTH);
mes = calendario.get(Calendar.MONTH);
mes++;
anyo = calendario.get(Calendar.YEAR);
System.out.println("dia " +dia);
System.out.println("mes " +mes);
System.out.println("año " +anyo);
if (mes == 1)
{
mes = 13;
anyo -= 1;
}
else if (mes == 2)
{
mes = 14;
anyo -= 1;
}

op1 = ((mes + 1) * 3) / 5;
System.out.println(op1);
op2 = anyo / 4;
System.out.println(op2);
op3 = anyo / 100;
System.out.println(op3);
op4 = anyo / 400;
System.out.println(op4);
op5 = dia + (mes * 2) + anyo + op1 + op2 + op4 + 2 - op3;
System.out.println(op5);
op6 = op5 / 7;
System.out.println(op6);
resultado = op5 - (op6 * 7);
System.out.println(resultado);

String dianacimiento = "";

switch (resultado)
{
case 0:
dianacimiento = "sábado";
break;
case 1:
dianacimiento = "domingo";
break;
case 2:
dianacimiento = "lunes";
break;
case 3:
dianacimiento = "martes";
break;
case 4:
dianacimiento = "miércoles";

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
break;
case 5:
dianacimiento = "jueves";
break;
case 6:
dianacimiento = "viernes";
break;
}
return dianacimiento;
}
}
Ahora veremos que tenemos una carpeta llamada Web Services en nuestro proyecto.
Vamos a probar el servicio para visualizar el formato de la respuesta y la entrada de datos.
Sobre nuestro servicio, seleccionaremos la opción Test Web Service.

Se nos abrirá el explorador mostrándonos la ubicación web del servicio.


http://localhost:8089/AplicacionWebServices/PrimerWebServiceService?Tester

Ahora ya podemos incluir una fecha con el formato que hemos elegido en el código y ya tenemos el
formato soap del servicio y la respuesta xml.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
SOAP Response

<?xml version="1.0" encoding="UTF-8"?>


<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getDiaNacimientoResponse xmlns:ns2="http://paqueteservicios/">
<return>miércoles</return>
</ns2:getDiaNacimientoResponse>
</S:Body>
</S:Envelope>

Y esta es la acción que realizará el servicio web en el servidor expresada de forma gráfica:

Ver Video: Creación de un cliente para consumir servicios web,


en la Unidad 13, en el Módulo 4, en la plataforma elearning

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Laboratorio: Consumir Servicio Web Externo
Objetivos
 Conocer el funcionamiento de acceso a clientes web utilizando la tecnología JAVA-WS.
 Acceso y consumo de recursos de un servicio web.
Enunciado
Para nuestra práctica vamos a utilizar un servicio web ya creado y gratuito que contiene información
y datos sobre el mundial 2010.
http://footballpool.dataaccess.eu/data/info.wso?WSDL
Lo primero de todo será crearnos un nuevo proyecto Web Application.

Lo llamaremos ConsumoServicioWeb

Utilizaremos el servidor GlassFish Server.

No agregaremos ningún Framework.


Vamos a agregar un cliente de servicio web. Para ello, seleccionamos sobre nuestro proyecto New
 Other

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Y en la carpeta Web Services, marcamos Web Service Client

Marcamos la opción WSDL y escribimos la dirección al servicio web del mundial 2010.
El estilo del cliente será utilizando la tecnología JAVA-WS

Veremos que nos ha creado una carpeta llamada Web Service Reference en la que tenemos la
información de todos los métodos que ofrece el servicio web.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Ahora vamos a crearnos una nueva clase para consumir los datos del servicio.

La llamaremos BeanWebService.

Sobre nuestra clase, bastará con arrastrar el método que necesitemos para poder realizar la llamada
al servicio. Hemos seleccionado el método AllGoalKeepers.

Si nos fijamos en la estructura, ya nos ha generado la llamada al servicio y los import necesarios.
Además, podemos comprobar que nos pide un String para poder invocar al método. También
podemos comprobar que devuelve un objeto del tipo ArrayOfString.
import eu.dataaccess.footballpool.ArrayOfString;
import eu.dataaccess.footballpool.ArrayOftTeamInfo;
private static ArrayOfString allGoalKeepers(java.lang.String sCountryName)
{
eu.dataaccess.footballpool.Info service = new eu.dataaccess.footballpool.Info();
eu.dataaccess.footballpool.InfoSoapType port = service.getInfoSoap();
return port.allGoalKeepers(sCountryName);
}

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Vamos a implementar el método para visualizar todos los porteros de un equipo. En nuestro
ejemplo utilizaremos Spain.
package paquetebeans;
import eu.dataaccess.footballpool.ArrayOfString;
import eu.dataaccess.footballpool.ArrayOftTeamInfo;
import java.util.List;
public class BeanWebService
{

private static ArrayOfString allGoalKeepers(java.lang.String sCountryName)


{
eu.dataaccess.footballpool.Info service = new eu.dataaccess.footballpool.Info();
eu.dataaccess.footballpool.InfoSoapType port = service.getInfoSoap();
return port.allGoalKeepers(sCountryName);
}

public void miMetodo()


{
ArrayOfString porteros = allGoalKeepers("spain");
List<String> datos = porteros.getString();
for (int i=0;i<datos.size();i++)
{
System.out.println(datos.get(i));
}
}
}
Si ejecutamos el servlet, podremos comprobar que muestra los nombres de los porteros de la
selección Spain.

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
Unidad 14. Implementación de una política
de seguridad
Introducción
Los servicios de seguridad de Java EE proporcionan un mecanismo robusto y fácilmente configurable
para autenticación y autorización de acceso en diferentes niveles:
 Aplicación.
 Transporte.
 Contenido de Mensajes.

Un mecanismo de seguridad implementado correctamente debe proporcionar la siguiente


funcionalidad:
 Prevenir accesos no autorizados a componentes y datos de la aplicación.
 Responsabilizar a los usuarios por las operaciones que realicen (non-repudiation).
 Facilitar su administración.
 Proporcionar mecanismos transparentes para los usuarios.
 Ser homogéneo a través de aplicaciones.

Existen varios mecanismos de seguridad que permiten realizar estas acciones:


 Identificación (identification): Mecanismo que permite el reconocimiento de una entidad
(usuario) por un sistema.
 Autenticación (authentication): Mecanismo por el cual los usuarios se validan y se comprueba
que existen en nuestro ámbito de seguridad.
 Autorización (authorization o access control): Mecanismo para asegurar que los usuarios
tienen permiso para realizar operaciones o para obtener acceso a la información.
 Integridad de datos (data integrity): Mecanismo usado para probar que la información no ha
sido modificada por usuarios no autorizados.
 Confidencialidad (confidentiality o data privacy): Mecanismo usado para asegurar que sólo
usuarios autorizados puedan ver cierta información.
 No-rechazo (non-repudiation): Mecanismo para impedir que un usuario niegue haber
realizado alguna operación.
 Auditoría (auditing): Mecanismo para capturar registros de operaciones, a prueba de
falsificaciones.

Objetivo
 Conocer los diferentes tipos de seguridad de aplicaciones.
 Visualizar el entorno del servidor para administrar seguridad con realms.
 Comprender los distintos métodos de validación de grupos y usuarios dentro del entorno Java
EE.

Implementación de la seguridad servidor y EJB


Existen diversas formas de configurar la seguridad dentro de las aplicaciones Java EE.

Seguridad a nivel de servidor


Una de las formas que podemos utilizar es mediante el servidor de aplicaciones. Dentro del
servidor, podemos utilizar diversos mecanismos de seguridad configurables:
 Creación y mantenimiento de políticas de seguridad.
 Administración de ámbitos “realms”.
 Altas, bajas y cambios de usuarios autorizados.
 HTTP e IIOP Listeners.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 Conectores.
 Inserción (plug-in) de otros programas de seguridad.
 Inserción (plug-in) de módulos de auditoría.

Seguridad a nivel declarativo (EJB)


La seguridad a nivel declarativo, implica que la seguridad se monta dentro de la propia aplicación
empresarial, utilizando anotaciones o archivos descriptores.
Para utilizar la seguridad a nivel declarativo se utilizan una serie de elementos que pueden formar
grupos o usuarios individuales, dependiendo del tipo de validación que deseamos utilizar.
 Realms: Colección de usuarios (que pueden o no pertenecer a un grupo) y grupos de
usuarios controlados por la misma política de seguridad.
Existen 3 tipos: file, admin y certificate realms.
 Users: Individuos (o programas de aplicación) definidos en el Servidor de aplicaciones.
 Groups: Conjuntos de usuarios clasificados normalmente por características comunes.
 Roles: Nombres abstractos que identifican los permisos para acceder a un conjunto de
recursos. Se mapean a grupos o roles.
 Principal: Una entidad (usuario o aplicación) que puede ser autenticado.
 Security policy: Es el alcance de una política de seguridad domain implementada por un
servicio de seguridad.
 Security attributes: Características de seguridad asociadas a un usuario.
 Credentials: Conjunto de security attributes usados para autenticar un principal.

Los servicios de seguridad de Java EE se implementan mediante una o algunas de las siguientes
formas:
 Anotaciones: La información de seguridad se especifica dentro de las mismas clases.
 Declarativa: La información de seguridad se especifica en el deployment descriptor. (Los
valores especificados en el descriptor sustituyen a los de las anotaciones.)
 Programática: Postulados embebidos en las clases.

Los Enterprise Java Beans (Session y Message Driven) pueden implementar la seguridad declarativa
y hace uso de la seguridad mediante las siguientes formas:
 Declarando nombres de roles referenciados desde el código del bean.
 Utilizando anotaciones.
 Utilizando elementos en un deployment descriptor.

Para poder utilizar dichas características, será necesario tener acceso al “contexto de seguridad”,
que es un objeto creado por el contenedor de EJB.
Para tener acceso a dicho contexto de seguridad se utiliza la siguiente nomenclatura de código:
@Resource SessionContext contextoseguro
contextoseguro.getCallerPrincipal( )
contextoseguro.isCallerInRole(String roleName)

Un ejemplo de seguridad utilizando el método getCallerPrincipal().


Dicho método valida los usuarios dentro del propio código y se validaría el nombre del usuario.
package newpackage;
import java.security.Principal;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
@Stateless
public class NewSessionBean {
@Resource SessionContext contextoseguridad;
@PersistenceContext EntityManager em;
public void CambiarNombre() {
//obtenemos el usuario Principal de la aplicación.
Principal usuarioPrincipal;
String nombreusuario;
usuarioPrincipal = contextoseguridad.getCallerPrincipal();
//Obtenemos el nombre del usuario.
nombreusuario = usuarioPrincipal.getName();
//Para buscar usuarios, enviamos la entidad
//y el nombre del usuario, que estaría validado en
//el método findByPrimaryKey
Emp empleado =
em.findByPrimaryKey(Emp.class, nombreusuario);
//Si llegamos a este punto, podriamos modificar los datos
//del usuario mediante métodos implementados...
empleado.setEName("oldname","newname");
}
}
Como podemos comprobar, los usuarios se validarían antes de la acción del método, y una vez
validados, el propio método comprobaría su nombre de usuario para poder realizar las acciones.
Otro tipo de validación se puede realizar con el método isCallerInRole(role), que permite validar
usuarios mediante grupos o roles a los que perteneces, no validaría un usuario Principal, sino que
utiliza anotaciones en el propio bean para definir los grupos de usuarios a los que se les permite
acceso:
package newpackage;
import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
@DeclareRoles("EJECUTIVOS")
@Stateless
public class NewSessionBean {
@Resource SessionContext contextoseguridad;

public void ModificarSalarioEmpleado(int nuevosalario, int idempleado) {


// El campo salario solamente puede ser
//modificado por usuarios que se encuentren
//dentro del rol EJECUTIVOS.
if (contextoseguridad.isCallerInRole("EJECUTIVOS")==false)
{
throw new SecurityException("No tiene permisos para modificar el salario");
}else{
//Acciones en la base de datos para modificar
//el salario de los empleados...
}
}
}
Los nombres de los roles usados en el código de los beans se pueden declarar de dos formas
diferentes:
 Utilizando la anotación @DeclareRoles (preferida)

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
 Usando la etiqueta en el fichero deployment descriptor.

Este role de seguridad permite poder modificar los datos de los empleados. Solamente están
admitidos los roles de EJECUTIVOS
<enterprise-beans>
<session>
<ejb-name> NewSessionBean</ejb-name>
<ejb-class> NewSessionBean</ejb-class>
<security-role-ref>
<description>
</description>
<role-name> EJECUTIVOS </role-name>
</security-role-ref>
</session>
...
</Enterprise-beans>
También podemos definir los permisos que necesitamos administrar a nivel de método de la clase.
Los permisos de métodos se pueden especificar a nivel de clase o a nivel de método (o ambos).
Para ello, debemos emplear las siguientes anotaciones:
 @RolesAllowed("lista de roles")
 @PermitAll
 @DenyAll

Un ejemplo para ofrecer permisos en los métodos sería el siguiente:


Código de la clase que permite acceso a los administradores
import javax.annotation.security.RolesAllowed;
@RolesAllowed("administrador")
public class MiClase
{
public void PrimerMetodo () {...}
public void SegundoMetodo () {...}
}
Código de la clase del Bean
import javax.ejb.Stateless;
@Stateless
public class NewSessionBean implements MiBean extends MiClase
{
@RolesAllowed("usuarios")
public void PrimerMetodo () {...}
public void SegundoMetodo () {...}
public void OtroMetodo () {...}
}
Si analizamos el código anterior, los administradores podrán obtener acceso a los dos método del
objeto “MiClase”, pero en el método PrimerMetodo(), también tendrán acceso los usuarios, mientras
que en el método SegundoMetodo() solamente podrán acceder los administradores como roles.

Mapeo de Roles a grupos


Otro tipo de seguridad que podemos implementar dentro de nuestras aplicaciones empresariales son
los mapeos de roles a grupos.
El Application Server asigna usuarios (Principals) a grupos no a roles.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
En el desarrollo, no es necesario conocer los grupos de usuarios que se han definido, sino
exclusivamente los roles.
La arquitectura de seguridad proporciona un mecanismo para mapear los roles definidos en la
aplicación a los usuarios o grupos definidos en el ámbito (realm) de seguridad de la aplicación.
Para hacer el mapeo se usa el elemento del deployment descriptor de la
aplicación (sun-application.xml, sun-web.xml o sun-ejb-jar.xml dependiendo del tipo de aplicación).
Ejemplo de un mapeo en un descriptor utilizando el archivo sun.apllication.xml:
<sun-application>
<security-role-mapping>
<role-name>BECARIOS</role-name>
<principal-name>Usuario</principal-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ADMINISTRADOR</role-name>
<group-name>directores</group-name>
</security-role-mapping>
</sun-application>
Los nombres de roles usados en la aplicación pueden ser iguales a nombres de grupos definidos en
el Servidor de aplicaciones.
En este caso, se puede habilitar un mapeo de default usando la Consola de
Administración de nuestro servidor. Para ello, tendríamos que seguir los siguientes pasos.
1) Iniciar al servidor (en nuestro ejemplo Glassfish)

2) Entrar en la consola de administración del servidor.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
3) Expandir el nodo Configuration.
4) Expandir el nodo Security.
5) Expandir el nodo Realms y seleccionar file.

6) Seleccionar manage users en la pantalla del realm file (dominio)

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
7) Escribiríamos todos los datos de cada uno de los usuarios que deseamos validar en nuestra
aplicación, incluido su nombre y su grupo o grupos a los que pertenece.

8) Cada uno de los usuarios que almacenamos se guardarán en el servidor y podremos utilizar
Roles en los archivos descriptores para acceder a dichos roles o el acceso mediante
anotaciones en las clases EJB.

Seguridad de aplicaciones web en servlets y jsp


Se utilizan las mismas técnicas de seguridad que para el caso de los Enterprise Beans:
 Declaración de roles de seguridad.
 Declaración de requerimientos de seguridad

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
También se utilizan otras técnicas específicas para el contenedor Web:
 Restricciones de seguridad.
 Conexiones seguras.
 Mecanismos de autenticación específicos.

Para poder crearnos Roles de seguridad tenemos dos formas de realizar la acción:
Mediante anotaciones en un servlet (por ejemplo)
@DeclareRoles("administrador")
public class MiServlet {
//CODIGO DEL SERVLET
}
Mediante el fichero web.xml:
<security-role>
<role-name> administrador</role-name>
</security-role>
También podemos especificar la seguridad propia de cada uno de los servlets en el fichero web.xml:
<servlet>
<security-role-ref>
<rol-name>admin</rol-name>
<rol-link>administrador</rol-link> Este sera el nombre del ROLE utilizando en el código del
servlet para la validación
</security-role-ref>
</servlet>
Al igual que con los EJB, podemos realizar mapeos de nombres a grupos, pero se escribirían en el
descriptor de la aplicación, no el fichero web.xml.
<sun-web-app>
<security-role-mapping>
<role-name>administradores</role-name>
<principal-name>admin1</principal-name>
<principal-name>admin2</principal-name>
</security-role-mapping>
<security-role-mapping>
<role-name>Becarios</role-name>
<group-name>beca</group-name>
</security-role-mapping>
..</sun-web-app>
Dentro de los servlets, tenemos tres métodos para implementar sobre la interfaz HttpServletRequest
que nos permiten el acceso a la información de seguridad:
 String getRemoteUser( )
 Principal getUserPrincipal()
 boolean isUserInRole(String roleName)

Por ejemplo, vamos a visualizar un servlet que valida los usuarios que se han conectado en nuestra
aplicación:
package newpackage;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.annotation.security.DeclareRoles;
www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.
@DeclareRoles({"admin", "user"})
public class ServletSeguridad extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<head>");
out.println("<title>Servlet ServletSeguridad</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet con Seguridad</h1>");
if (request.isUserInRole("admin"))
{
out.println("Bienvenido administrador");
out.println("TIENE TODOS LOS PERMISOS");
}
if (request.isUserInRole("user"))
{
out.println("Bienvenido USUARIO");
out.println("SUS PERMISOS SON LIMITADOS...");
}
out.println("</body>");
out.println("</HTML>");
} finally {
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}

Ver Video: Validación de usuarios, en la Unidad 14, en el


Módulo 4, en la plataforma elearning

Actividades
“Recuerde que para un seguimiento óptimo de la unidad es imprescindible realizar las
actividades que encontrará en la unidad correspondiente de la plataforma eLearning”.

www.learning.es
Para uso exclusivo de los alumnos de LEARNING & TRAINING CLOUD, S.L.

También podría gustarte