Este documento describe una aplicación que ofrece servicios web RESTful y SOAP para recuperar tweets e información sobre estudios clínicos almacenados en una base de datos. La aplicación consta de dos proyectos: un servidor que implementa los servicios y un cliente que los consume. Los servicios RESTful permiten recuperar datos mediante solicitudes HTTP mientras que los servicios SOAP usan SOAP sobre HTTP. El documento explica los detalles de implementación de ambos tipos de servicios.
Parámetros de Perforación y Voladura. para Plataformas
Web Services JAX-RS RESTful y SOAP
1. Práctica V: Web Services JAX-RS RESTful y SOAP
EQUIPO DE TRABAJO:
2. 0-Código de la Práctica Web Services 2016
➢ La aplicación esta compuesta por dos proyectos:
1. APITwitterTagV2 (Servidor Web)
2. JAXClient (Cliente)
Pueden ser descargados del repositorio SVN de la UNED accediendo a:
http://62.204.199.127/JAVA_UNED/alef/browser/UNED_2016/J2EE/APITwitterWS/trunk
➢ Descarga del código del repositorio mediante TortoiseSVN (https://tortoisesvn.net/downloads.html)
Nuestro compañero Jose, realizó un vídeo explicativo para poner en marcha ambas aplicaciones partiendo del
repositorio. Es importante recalcar, que las librerias necesarias son descargadas con el proyecto y debemos
configurar nuestro "Build Path" de acuerdo a lo indicado en el video:
http://62.204.199.127/alef/UNED_2016/J2EE/APITwitterWS/19563377-sesionPruebas.ogv.bin
➢ Descarga de la BBDD del repositorio en:
https://62.204.199.127/alef/UNED_2016/J2EE/APITwitterWS/apitwitter.sql
3. 1-Punto de partida
La aplicación en su conjunto esta formada por dos proyectos y una BBDD:
➢ ApiTwitterTagV2 → Servidor de servicios.
➢ JAXClient → Consumidor de servicios.
➢ Apitwitter.sql → BBDD en la que se almacena información sobre Tweets (extraídos con anterioridad de la API de
Twitter) y Estudios Clínicos (extraídos con anterioridad de la API de ClinicalTrials) mediante el Crawler “ApiTwitter”.
NOTA: Para más información sobre el funcionamiento del Crawler o Robot consultar:
http://62.204.199.127/JAVA_UNED/alef/wiki/2016_practica_APITwitter
4. 2-Servicios Web
Se han desarrollado cinco servicios Web:
1. Recuperar Tweets partiendo de un Hashtag elegido por el Cliente.
2. Recuperar un Tweet partiendo de su Id. Cada Tweet dispone de un identificador único. Este es seleccionado por el
Cliente (consumidor del servicio) y el Servicio Web recupera el Tweet correspondiente.
3. Recuperar Estudios Clínicos partiendo de un Hashtag elegido por el Cliente. Para no extender este
documento, nos centraremos en la explicación de este servicio en su dos metodologías: Restful y Soap.
4. Recuperar un Estudio Clínico partiendo de su NCT. Cada Estudio Clínico dispone de un identificador único (nct).
Este es seleccionado por el Cliente (consumidor del servicio) y el Servicio Web recupera el Estudio Clínico
correspondiente.
5. Recuperar Hashtag vecinos partiendo de un Hashtag seleccionado por el Cliente (consumidor del servicio). El
Servicio Web recupera un listado de Hashtags vecinos.
Nota: Dado un Hashtag concreto podemos localizar Tweets relacionados. Dentro de estos Tweets también existen
nuevos Hashtags que nos llevarán a su vez a nuevos Tweets relacionados con un tema concreto. A estos Hashtags
los denominamos→ Neighbour (vecinos)
5. 3-Estudios Clínicos partiendo de un Hashtag→web.xml →RESTful
➢ El archivo web.xml se encuentra en la ruta WebContent/Web-INF
➢ Para añadir los servicios RESTful es necesario indicar:
➢ El provider JAX-RS de referencia, jersey
➢ Las aplicaciones jersey
➢ Los mappings para ejecutar los servicios JAX-RS
6. 4-Recuperar Estudios Clínicos partiendo de un Hashtag→RESTful
Esquema de paquetes empleados en Servidor (APITwitterTagV2):
4.1 uned.java2016.apitwitter.dao
4.2 uned.java2016.apitwitter.services.rs (RESTful)
4.2.1 uned.java2016.apitwitter.services.rs.EstudioService.java
4.2.2 uned.java2016.apitwitter.services.rs.RSApplication.java
4.3 uned.java2016.apitwitter.services.rs.filters (RESTful)
4.4 uned.java2016.apitwitter.services.rs.jaxb (RESTful)
7. 4.1 uned.java2016.apitwitter.dao
➢ En este paquete se estable el [Objeto de Acceso a Datos] denominado: Estudio Clínico
➢ Dicho objeto tiene tanto los atributos como los métodos necesarios para la gestión de la información
extraída de un Estudio Clínico.
➢ Destaca “nctId” en su papel de identificador unívoco.
➢ Las clases de este paquete serán requeridas por el servicio WEB para lograr la funcionalidad.
8. 4.2 uned.java2016.apitwitter.services.rs → RESTful
➢ Se crea la clase EstudiosService.java.
➢ Dicha clase implementa el Servicio Web 'estudios'
➢ Se publica en el path 'estudios' bajo el que opera Jersey
9. 4.2.1 uned.java2016.apitwitter.services.rs.EstudiosService.java
Nos centramos en la clase EstudiosService.java:
➢ Programación (RESTful) mediante anotaciones en Java:
➢ @GET
➢ @Path("/getByHashtag/{ht: [a-zA-Z]+}/{count: [0-9]{1,2}}")
➢ @Produces({MediaType.APPLICATION_XML})
➢ Método getEstudio→Recupera los estudios que contienen el hashtag elegido por el usuario
Parámetros:
➢ @param ht → Hashtag
➢ @param count → Numero de estudios a recuperar
➢ @return → Estudios que contienen el hashtag 'ht'
12. 4.3 uned.java2016.apitwitter.services.rs.filters (RESTful)
➢ Filtro de autenticación para todos los servicios RESTful.
➢ Espera una cabecera 'Authorization' con las credenciales según el esquema <user>:<password>
➢ Accede a la BBDD y comprueba si el usuario tiene perfil 'adm'.
➢ Si no, aborta la ejecución de la llamada al WS y devuelve el error 401 UNAUTHORIZED
14. 5-Recuperar Estudios Clínicos partiendo de un Hashtag→SOAP
5.1 Implementar el servicio JAX-WS con el modelo de Servlet.
Existen dos métodos para implementar el desarrollo en Soap:
• Partir de una clase Java que implemente el servicio Web.
• Un fichero WSDL (formato XML que describe un servicio Web).
En nuestro caso hemos elegido la primera opción.
15. 5.2 Esquema de paquetes y clases
Se han introducido dos nuevos paquetes para desarrollar los Servicios Web SOAP:
➢ 5.2.1 uned.java2016.apitwitter.services.soap
▪ 5.2.1.1 uned.java2016.apitwitter.services.soap.EstudioServiceImpl.java
Clase EstudioServiceImpl.java (Detalle Método getByHashtag)
▪ 5.2.1.2 uned.java2016.apitwitter.services.soap.EstudioService.java (Interface)
➢ 5.2.2 uned.java2016.apitwitter.services.jaxws
17. ➢ La clase EstudioServiceImpl.java con la anotación @WebService tiene dos métodos de implementación:
1- Define un SEI (Service Endpoint Interface) de forma implícita por lo que no será necesario
proporcionar dicha interfaz.
2- Especificando de forma explícita una interfaz añadiendo el atributo endpointInterface a la anotación
@WebService. En ese caso, sí es necesario proporcionar la interfaz que defina los métodos
públicos disponibles en la clase que implementa el servicio.
➢ La anotación @WebService no precisa que se especifique la ubicación del WSDL. Si se utiliza el atributo
wsdlLocation en la anotación @WebService, el fichero WSDL debe ser empaquetado junto con las clases
java del servicio web.
➢ En la variable context, se inyectará un objeto WebServiceContext. De esta forma tendremos acceso al
contexto del servicio. Como el servicio es un componente web, a través de este objeto podremos tener
acceso a componentes de la API de servlets como a la petición HTTP (HttpServletRequest), la sesión
(HttpSession), etc.
18. Clase EstudioServiceImpl.java (Detalle Método getByHashtag)
Detalle del método getByHashtag:
Mediante el método getByHashtag se accede a la BBDD mediante los métodos del DAO y se retorna una lista
de los Estudios Clínicos partiendo de un Hashtag elegido por el usuario.
➢ El método getByHashtag dispone de los parámetros de entrada:
➢ ht → Hashtag (String de búsqueda en la BBDD)
➢ count → Número de Objetos Estudios a recuperar
➢ El método devuelve Estudios que contienen el Hashtag 'ht'.
20. 5.3 Despliegue del servicio web en el Servidor
➢ Define la configuración del despliegue en los ficheros:
4.3.1 web.xml
4.3.2 sun-jaxws.xml
➢ Se utiliza el modelo de despliegue específico de JAX-WS RI, que define la configuración del despliegue en los
ficheros web.xml y sun-jaxws.xml.
➢ Se trata de un despliegue sin descriptores, por tanto la implementación de nuestro servicio web no sería
"descubierta" automáticamente por el contenedor (por ejemplo Tomcat).
➢ Debemos incluir descriptores de despliegue para "decirle" a la librería JAX-WS cómo queremos que se
desplieguen nuestros servicios web.
➢ En nuestro caso, que utilizamos Tomcat, tendríamos que añadir en el directorio WEB-INF los ficheros sun-
jaxws.xml y web.xml. Ambos ficheros contendrán información para realizar el "despliegue" de los servicios web.
21. 5.3.1 web.xml
En el fichero web.xml declaramos el listener JAX-WS WSServletContextListener, que inicializa y configura el
endpoint (componente port) del servicio web, y el servlet JAXWS WSServlet, que es el que sirve las peticiones al
servicio, utilizando la clase que implementa dicho servicio.
El contenido de nuestro fichero web.xml quedaría así:
22. 5.3.2 sun-jaxws.xml
El fichero sun-jaxws.xml contiene la definición de la implementación del endpoint del servicio. Cada endpoint representa
un port WSDL, y contiene toda la información sobre la clase que implementa el servicio, url-pattern del servlet,
información de binding, ubicación del fichero WSDL, y nombres "cualificados" (qualified names) del port y service del
WSDL.
Si no especificamos la ubicación del fichero WSDL, éste será generado y publicado durante el despliegue. En el
siguiente fichero sun-jaxws.xml indicamos que la implementación de nuestro servicio viene dada por la clase
uned.java2016.apitwitter.services.EstudioServiceImpl.java (dicha clase debe estar anotada con @WebService).
23. 5.3.3 Herramienta de despliegue wsgen y generación de clases
➢ La herramienta de despliegue comienza el proceso examinando el artefacto desplegado para determinar qué
módulos contienen servicios Web, para ello analiza las anotaciones de servicios web o los descriptores de
despliegue contenidos en el módulo. A continuación, obtiene la información de enlazado (binding), despliega los
componentes y servicios web definidos en el módulo. Seguidamente publica los documentos WSDL que
representan a los servicios web desplegados, configura al servidor e inicia la aplicación.
➢ wsgen→herramienta para generar servicios web a partir de una clase java.
➢ Proceso:
1. Lo primero que deberemos hacer es compilar la clase que implementa el servicio al igual que cualquier otra
clase Java, con la herramienta javac.
2. Generaremos el servicio con wsgen a partir de la clase compilada. Sobre la línea de comandos lanzamos la
herramienta wsgen del siguiente modo:
wsgen -cp <classpath> -s <src.dir> -d <dest.dir> <nombre.clase.servicio>
3. La clase que implementa el servicio (<nombre.clase.servicio>) se especificará mediante su nombre completo,
es decir, incluyendo el nombre del paquete al que pertenece.
4. En el caso concreto del servicio EstudioService definido anteriormente, podríamos generar las clases
necesarias de la siguiente forma:
wsgen -s src -d build/classes -cp build/classes uned.java2016.apitwitter.services.soap.EstudioServiceImpl
24. ➢ Para comprobar que el nuestro servicio web esta desplegado, podemos acceder a su definición WSDL a
través de la dirección:
http://localhost:8080/APITwitterWeb/services/soap/ClinicalStudyWS?wsdl
➢ Con esto se generarán una serie de clases en el servidor que implementan el servicio web. Se crean en el
paquete:
4.2.2 uned.java2016.apitwitter.services.soap.estudios.jaxws
25. 5.4 Despliegue del servicio web en el Cliente
➢ A partir de JDK 1.6 se incluye en Java SE la librería JAX-WS y las herramientas necesarias para crear e
invocar servicios. Podemos encontrar las clases de la API de JAX-WS dentro del paquete javax.xml.ws.
➢ Para crear un cliente en JDK 1.6 (o con JAX-WS en versiones anteriores de JDK) utilizaremos la
herramienta: wsimport.
➢ wsimport:
1. Toma como entrada el documento WSDL del servicio al que queremos acceder y producirá un conjunto
de clases Java que nos permitirán acceder al servicio.
2. Esta herramienta se puede invocar desde línea de comando del siguiente modo:
wsimport -s <src.dir> -d <dest.dir> -p <pkg> <wsdl.uri>
<src.dir>→ directorio donde queremos que guarde los fuentes de las clases generadas
<dest.dir>→ directorio donde guardará estas clases compiladas
<pkg>→paquete en el que se generará este conjunto de clases (<pkg>)
<wsdl.uri>→El WSDL se especificará mediante su ruta en el disco o mediante su URL.
26. 3. Para generar los artefactos del lado del cliente a partir del servicio web previamente creado debemos
ejecutar en línea de comandos:
wsimport -keep -verbose http://localhost:8080/APITwitterWeb/services/soap/ClinicalStudyWS?wsdl
4. Se generarán una serie de clases que nos permitirán acceder al servicio web e invocar sus operaciones
desde nuestro cliente.
Una de estas clases recibirá el mismo nombre que el servicio y heredará de la clase Service.
27. 5.5 Programando la “Vista” en Swing Cliente
1. Centrandonos en el controlador de Swing “SwingSOAPController.java”. En nuestro caso, dentro del
paquete:
package uned.java2016.apitwitter.services.rs.client;
2. Deberemos instanciar la clase generada anteriormente “EstudioServiceImplService” y a partir de ella
obtendremos el stub para acceder a un puerto del servicio. Este stub tendrá la misma interfaz que el
servicio web, y a partir de él podremos invocar sus operaciones.
28. 3. En nuestro ejemplo de Servicio SOAP “Obtener Estudios Clínicos partiendo de un Hashtag elegido por
el usuario accederíamos de la siguiente forma:
Detalle de SwingSOAPController.java: