Proyecto de Integración
 

Integración con Servicios Web

Introducción

En esta sesión de integración vamos a ofrecer como servicio web algunas de las operaciones implementadas mediante EJBs en sesiones anteriores. También utilizaremos un servicio web externo para obtener información extendida sobre los libros de nuestra biblioteca. Por último, crearemos un cliente Java para uno de nuestros servicios.

Nota
Para realizar el trabajo de esta sesión partiremos del resultado de la sesión de integración con JSF.

Creación de servicios web

Vamos a implementar un servicio web para obtener información de los libros. Crearemos un nuevo proyecto web Maven con nombre jbib-web-services. Como groupID elegiremos el valor org.especialistajee.proyint. La versión que vamos a crear será la 1.0.

Nuestro proyecto necesita acceder tanto al proyecto común jbib-comun como al proyecto jbib-negocio-ejb por lo que añadiremos las dependencias correspondientes en nuestro pom. Pondremos el scope a provided. Con esto estamos indicando que los jar y war anteriores se necesitarán para compilar el proyecto jbib-web-services pero no se incluirán en el empaquetado final del mismo. La siguiente figura muestra estas dependencias:

Dependencias con ámbito provided con proyectos anteriores

Además, nuestro proyecto tiene que incluirse como un módulo de la aplicación jbib-enterprise, para que pueda acceder al EJB. Para ello añadiremos nuestro proyecto jbib-web-services1.0 como un módulo en el pom de la aplicación Enterprise. La siguiente figura muestra dichas dependencias:

Módulos del proyecto Enterprise

Recuerda que cuando creamos un proyecto Maven desde Netbeans, por defecto no se asocia dicho proyecto a ningún servidor de aplicaciones. Tendremos que indicarle manualmente cuál es el servidor asociado pulsando con el botón derecho sobre el proyecto en Propiedades, desde la opción Run

Nota
Las dos imágenes anteriores podréis verlas pinchando con el botón derecho en cada uno de los proyectos, con la opción Show dependency graph. Nos aparecerá un grafo con las dependencias de dicho proyecto, que podremos mostrar en varios niveles.
Importante
Recuerda que cuando creamos un proyecto Maven desde Netbeans, por defecto no se asocia dicho proyecto a ningún servidor de aplicaciones. Tendremos que indicarle manualmente cuál es el servidor asociado pulsando con el botón derecho sobre el proyecto en Propiedades, desde la opción Run. Si no asociamos el servidor, la opción de Netbeans para crear un cliente a partir de un EJB nos aparecerá "desactivada".

El proyecto jbib-web-services contendrá el servicio web que va a ofrecer nuestra aplicación. Aquí vamos a crear un servicio web LibroWS en el paquete org.especialistajee.jbib.ws, a partir del EJB LibroBoEjb. Concretamente, las operaciones que deberá ofrecer este servicio son:

  • LibroDomain recuperaLibro(String isbn)
  • List<LibroDomain> listaLibros()
Nota
Para que estas operaciones se añadan automáticamente al generar el servicio web a partir del EJB, deberán figurar en la interfaz local del EJB (LibroBoLocal). Dado que, debido a la forma de crear los EJBs en sesiones anteriores, es posible que dicha interfaz esté vacía, tendremos dos opciones alternativas: (1) añadir los métodos que queramos exportar como servicios a la interfaz local del EJB, o (2) crear el servicio web sin operaciones y añadirlas a mano posteriormente.

La operación recuperaLibro nos devuelve los datos del libro solicitado a partir de su isbn. La seguna operación permitirá a un cliente externo obtener los datos de todos los libros de nuestra biblioteca.

Acceso a servicios web externos

Vamos a añadir a la aplicación la funcionalidad de obtener los detalles de un libro (portada, precio, editorial y fecha de publicación). Para hacer esto recurriremos a un servicio web que hemos creado en el servidor de jtech para el curso de especialista, y al que denominaremos servicio web de Jtech. Seguiremos los siguientes pasos:

Primero añadimos al paquete org.especialistajee.jbib.model.to del proyecto común (jbib-comun) un nuevo Transfer Object que extienda LibroDomain para añadir atributos adicionales a los libros:

public class LibroCatalogoTO extends LibroDomain {

  float precio;
  String imagen;
  int imagenAncho;
  int imagenAlto;
  String editorial;
	
  // Getters y setters
  ...	

}

Creamos dentro del módulo EJB (jbib-negocio-ejb) un cliente para acceder al servicio web de Jtech, cuyo documento WSDL se puede encontrar en la siguiente dirección:

server.jtech.ua.es/servcweb-catalogo-jtech/CatalogoSWService?wsdl
Muy importante
Debido a un bug de Glassfish, la inyección de la referencia al servicio web (anotación @WebServiceReference) no funciona correctamente, de forma que, al ejecutar el servicio web, el servidor no encuentra el wsdl asociado a dicha referencia. En consecuencia, no se crea la instancia del stub del servicio en el cliente, y la llamada para obtener el puerto del servicio provocará una excepción. Para solucionar este problema tendremos que quitar la anotación, y en su lugar, crearemos "a mano" nosotros dicha instancia en lugar de dejar que Glassfish lo haga. Por lo tanto añadiremos la línea service = new CatalogoSWService(); antes de realizar la llamada al método service.getCatalogoSWPort();.

Añadimos al EJB LibroBoEjb un nuevo método recuperaLibroCatalogo, que tomará como parámetro el ISBN del libro que buscamos, y nos devolverá un objeto LibroCatalogoTO con los datos de dicho libro, accediendo para ello al servicio web de Jtech.

Opcional
Si queréis probar el servicio web de Jtech lo podéis hacer accediendo a: server.jtech.ua.es/servcweb-catalogo-jtech/CatalogoSWService?Tester

Finalmente tenemos que realizar las modificaciones correspondientes en el proyecto jbib-web-jsf para que se muestre en pantalla el resultado de la llamada al servicio web de Jtech y nos aparezca la carátula del libro seleccionado, su título, isbn, y precio en euros.

Para ello, en la carpeta de fuentes (org.especialistajee.jbib.jsf) modificaremos los ficheros DetalleLibroBean.java y UsuarioBean.java. En el fichero DetalleLibroBean.java añadimos la variable LibroCatalogoTO libroCatalogo; con sus correspondientes métodos getLibroCatalogo y setLibroCatalogo. En el fichero UsuarioBean.java también tenemos que añadir la variable detalleLibroBean que anotaremos como propiedad gestionada:

  
  @ManagedProperty(value = "#{detalleLibroBean}")
  DetalleLibroBean detalleLibroBean;

Igual que antes, añadiremos también los métodos get y set correspondientes. La última modificación que tendremos que hacer en este fichero UsuarioBean.java es añadir la acción public String doDetalleLibroCatalogo() para asignar el valor correspondiente a la variable detalleLibroBean.

Dentro del directorio Web Pages, en la carpeta libro, crearemos el fichero detalleLibroCatalogo.xhtml para mostrar los datos: imagen del libro, isbn, título y precio JTech

En la subcarpeta usuario de Web Pages tendremos que modificar el contenido de listadoLibros.xhtml de forma que el campo isbn que se muestra por pantalla tenga asociada la acción "#{usuarioBean.doDetalleLibroCatalogo}.

<a4j:commandLink value="#{libro.isbn}" action="#{usuarioBean.doDetalleLibroCatalogo}" 
       render="panelCatalogo" oncomplete="#{rich:component('popup-catalogo')}.show();">
    <f:setPropertyActionListener target="#{usuarioBean.libroSeleccionado}" value="#{libro}" />
</a4j:commandLink>

En este caso el renderizado (atributo render) tendrá el valor "panel-catalogo". Al atributo oncomplete le indicaréis que muestre un nuevo rich:component llamado "popup-catalogo", de forma que tendréis que añadir un nuevo popupPanel identificado como "popup-catalogo". Para que el popup ajuste su tamaño al contenido mostrado tendréis que añadir el atributo autosize=true.

<rich:popupPanel id="popup-catalogo" autosized="true"> 
   ...

A continuación mostramos los ficheros que hemos modificado del proyecto jbib-web-jsf

Ficheros modificados/añadidos del proyecto jbib-web-jsf

La siguiente figura muestra el resultado final, suponiendo que hemos accedido a la aplicación como el usuario aitor y hemos selelccionado el isbn del libro EJB 3 in action:

Resultado de la integración de servicios web

Cliente para los servicios web

Crear un cliente Java con Netbeans para nuestro servicio web de la biblioteca, en un nuevo proyecto Maven Java al que llamaremos jbib-web-services-client. Nuestra clase principal estará en el paquete org.especialistajee.jbib.ws.client. El groupID será org.especialistajee.proyint, y la versión, la 1.0

El programa deberá invocar la operación listaLibros y mostrar en la consola el listado de libros.

De cada libro se mostrará su ISBN, su título, y su autor.

Resumen

Estructura de los Proyectos

Se deberá añadir un nuevo proyecto jbib-servc-web con el siguiente servicio web:

  • LibroWS: Servicio web que ofrecerá las operaciones recuperaLibro, listaLibros.

Se deberán añadir el siguiente componente al módulo jbib-comun:

  • LibroCatalogoTO: Transfer Object con los datos detallados de un libro proporcionados por Jtech.

Se deberá añadir al módulo jbib-negocio-ejb:

  • Cliente del servicio de Jtech: Stub para acceder a los servicios de Jtech.
  • Operación recuperaLibroCatalogo en LibroBoEjb: Obtiene los datos detallados de un libro mediante los servicios de Jtech.

Se deberán añadir y/o modificar los siguientes componentes del módulo jbib-web-jsf:

  • (en Web Pages): Añadir DetalleLibroCatalogo.xhtml: contiene la composición del panel del popup que muestra los datos del servicio web externo.
  • (en Web Pages): Modificar listadoLibros.xhtml: contiene la modificación de los datos de la columna ISBN para que enlacen con la acción usuarioBean.doDetalleLibroCatalogo .
  • (en directorio de fuentes): Modificar DetalleLibroBean.java para incluir la variable libroCatalogo y los métodos get y set correspondientes.
  • (en directorio de fuentes): Modificar UsuarioBean.java para incluir la variable detalleLibroBean y los métodos get y set correspondientes. También añadiremos la acción doDetalleLibroCatalogo.

Se deberá añadir un nuevo proyecto jbib-web-services-client con un cliente Java que acceda a nuestro servicio. Obtendrá la lista de todos los libros, y la mostrará por la consola.

A entregar...
Deberéis entregar los proyectos jbib-comun, jbib-negocio-ejb, jbib-web-services, jbib-web-services-client