Creación de Webservice Cliente SOAP básico
Vamos a ver hoy la forma en la que debe implementarse un servicio cliente que deba consumir el endpoint publicado por un webservice SOAP desarrollado en la parte del servidor. Como ya sabemos, un webservice en realidad constará de dos partes: el servicio del servidor que es el que proporciona la información y el servicio del cliente que es el que precisa obtener dicha información. De hecho, en muchas ocasiones ambos servicios estarán desarrollados por equipos pertenecientes a proyectos y aplicaciones diferentes.
Hace
algunas semanas estuvimos viendo en el blog los pasos necesarios para
llevar a cabo la creación de un webservice sencillo. Al finalizar el
trabajo, dicho webservice quedó publicado en un endpoint predeterminado.
La idea es que hoy implementemos un servicio en la parte cliente que
sea capaz de consumir la lógica publicada por dicho webservice. Vamos
con ello.
Creación de Webservice Cliente SOAP
Teniendo en cuenta que ya tenemos creado un webservice publicado y listo para consumir, estos serían los pasos para la creación del servicio cliente.
1º) En primer lugar, tenemos que recuperar la ubicación del fichero WSDL del servicio publicado al que queremos acceder. En nuestro ejemplo, recordemos que la ruta era la siguiente:
http://localhost:8080/WebserviceSoapApp/ws/hola?wsdl
2º) Con esa información, vamos a lanzar la utilidad WSIMPORT. A partir del WSDL, esta utilidad es capaz de generar las clases necesarias para poder invocar al webservice desde cualquier otro proyecto que actúe como cliente.
Para poder ejecutarla, tendremos que ubicarnos en la carpeta "bin" del JDK que tengamos instalado en nuestro equipo. En mi caso, se trata de este directorio:
C:\Program Files\Java\jdk1.8.0_191\bin
3º) Abrimos la línea de comandos de Windows con "cmd". Por si acaso, os recuerdo que tendréis que abrirla en modo Administrador. Nos situamos en la carpeta "bin" del JDK.
cd C:\Program Files\Java\jdk1.8.0_191\bin
Generación de clases mediante WSIMPORT
4º) A continuación, para ejecutar WSIMPORT tendremos que usar el siguiente comando.
wsimport -keep -p com.universo.soap.client http://localhost:8080/WebserviceSoapApp/ws/hola?wsdl
Básicamente, le estamos indicando dos cosas:
- La ubicación del WSDL del servicio:
- http://localhost:8080/WebserviceSoapApp/ws/hola?wsdl
- El paquete en el que queremos que se generen las clases:
- com.universo.soap.client
5º) Una vez finalizada la ejecución del WSIMPORT, podremos comprobar que se han generado las clases necesarias en la carpeta correspondiente. Como nosotros hemos indicado el paquete "com.universo.soap.client", pues las clases se habrán creado en el directorio "com\universo\soap\client" que colgará de la carpeta "bin" en la que estamos situados. Por ejemplo, en mi caso las clases se han generado en el directorio:
C:\Program Files\Java\jdk1.8.0_191\bin\com\universo\soap\client
Si habéis seguido los mismos pasos, vosotros también deberíais tener algo parecido a esto:
Como se aprecia, se han creado dos clases a partir del WSDL proporcionado:
- Hola.java
- HolaService.java
6º) Le echamos un vistazo al contenido de las clases generadas, para ver cuál es el software añadido por la herramienta WSIMPORT.
👉 Este es el código de la clase Hola.java. Como vemos, se trata de una Interface que simplemente hace referencia a los métodos implementados por el servicio publicado en el lado del servidor.
// **************************************************
package com.universo.soap.client;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Action;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.9-b130926.1035
* Generated source version: 2.2
*
*/
@WebService(name = "Hola", targetNamespace = "http://server.soap.universo.com/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface Hola {
/**
*
* @param arg0
* @return
* returns java.lang.String
*/
@WebMethod
@WebResult(partName = "return")
@Action(input = "http://server.soap.universo.com/Hola/ciaoRequest",
output = "http://server.soap.universo.com/Hola/ciaoResponse")
public String ciao(
@WebParam(name = "arg0", partName = "arg0")
String arg0);
}
// **************************************************
👉 Y este es el contenido de la clase HolaService.java. Esta clase es la que implementa todo el contenido necesario para ejecutar el webservice desde el lado del cliente. Los valores de todos los atributos que aparecen en la clase no se han creado de forma aleatoria, sino que se han generado en función de las indicaciones incluidas en el WSDL del servicio.
// **************************************************
package com.universo.soap.client;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.9-b130926.1035
* Generated source version: 2.2
*
*/
@WebServiceClient(name = "HolaService",
targetNamespace = "http://server.soap.universo.com/",
wsdlLocation = "http://localhost:8080/WebserviceSoapApp/ws/hola?wsdl")
public class HolaService
extends Service
{
private final static URL HOLASERVICE_WSDL_LOCATION;
private final static WebServiceException HOLASERVICE_EXCEPTION;
private final static QName HOLASERVICE_QNAME =
new QName("http://server.soap.universo.com/", "HolaService");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("http://localhost:8080/WebserviceSoapApp/ws/hola?wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
HOLASERVICE_WSDL_LOCATION = url;
HOLASERVICE_EXCEPTION = e;
}
public HolaService() {
super(__getWsdlLocation(), HOLASERVICE_QNAME);
}
public HolaService(WebServiceFeature... features) {
super(__getWsdlLocation(), HOLASERVICE_QNAME, features);
}
public HolaService(URL wsdlLocation) {
super(wsdlLocation, HOLASERVICE_QNAME);
}
public HolaService(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, HOLASERVICE_QNAME, features);
}
public HolaService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public HolaService(URL wsdlLocation, QName serviceName, WebServiceFeature... features)
{
super(wsdlLocation, serviceName, features);
}
/**
*
* @return
* returns Hola
*/
@WebEndpoint(name = "HolaPort")
public Hola getHolaPort() {
return super.getPort(new QName("http://server.soap.universo.com/", "HolaPort"),
Hola.class);
}
/**
*
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.
* Supported features not in the <code>features</code> parameter will have their
* default values.
* @return
* returns Hola
*/
@WebEndpoint(name = "HolaPort")
public Hola getHolaPort(WebServiceFeature... features) {
return super.getPort(new QName("http://server.soap.universo.com/", "HolaPort"),
Hola.class, features);
}
private static URL __getWsdlLocation() {
if (HOLASERVICE_EXCEPTION!= null) {
throw HOLASERVICE_EXCEPTION;
}
return HOLASERVICE_WSDL_LOCATION;
}
}
// **************************************************
Creación de Proyecto Cliente
7º) Llegados a este punto, ahora nos toca crearnos un proyecto para alojar las clases generadas por la herramientoa WSIMPORT. Para ello, nos creamos un proyecto de tipo "Dynamic Web Project" en Eclipse.
A continuación, marcamos el proyecto y seleccionamos la opción CONFIGURE - CONVERT TO MAVEN PROJECT.
Se nos debería quedar una estructura del siguiente tipo:
8º) Nos creamos un paquete denominado "com.universo.soap.client" (recordad, este fue el paquete que indicamos al lanzar la generación de clases mediante WSIMPORT). Dentro de dicho paquete copiamos las clases previamente generadas: Hola.java y HolaService.java
Tras estas acciones, la estructura de nuestro proyecto quedará del siguiente modo.
9º) A continuación, añadimos el proyecto al TOMCAT y procedemos a arrancar el servidor. Si hemos seguido los pasos correctamente, el arranque debería completarse sin errores.
jul 01, 2021 1:28:29 PM org.apache.catalina.core.StandardEngine startInternal
INFORMACIÓN: Starting Servlet engine: [Apache Tomcat/9.0.36]
jul 01, 2021 1:28:30 PM org.apache.jasper.servlet.TldScanner scanJars
INFORMACIÓN: Al menos un JAR, que se ha explorado buscando TLDs, aún no contenía TLDs. Activar historial de depuración para este historiador para una completa lista de los JARs que fueron explorados y de los que nos se halló TLDs. Saltarse JARs no necesarios durante la exploración puede dar lugar a una mejora de tiempo significativa en el arranque y compilación de JSP .
jul 01, 2021 1:28:30 PM org.apache.jasper.servlet.TldScanner scanJars
INFORMACIÓN: Al menos un JAR, que se ha explorado buscando TLDs, aún no contenía TLDs. Activar historial de depuración para este historiador para una completa lista de los JARs que fueron explorados y de los que nos se halló TLDs. Saltarse JARs no necesarios durante la exploración puede dar lugar a una mejora de tiempo significativa en el arranque y compilación de JSP .
jul 01, 2021 1:28:30 PM org.apache.coyote.AbstractProtocol start
INFORMACIÓN: Starting ProtocolHandler ["http-nio-8080"]
jul 01, 2021 1:28:30 PM org.apache.catalina.startup.Catalina start
INFORMACIÓN: Server startup in [555] milliseconds
Probando el Webservice SOAP
10º) A continuación, para probar el servicio SOAP, vamos a crearnos una clase que lance una invocación contra el webservice situado en el lado del servidor. Para ello, nos situamos en el paquete "com.universo.soap.client" y nos creamos una clase HolaTest.java con el siguiente contenido.
// **************************************************
package com.universo.soap.client;
public class HolaTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
HolaService service = new HolaService();
Hola hola = service.getHolaPort();
String nombre = "Giuliano";
String respuesta = "";
respuesta = hola.ciao(nombre);
System.out.println(respuesta);
}
}
// **************************************************
11º) Finalmente, ejecutamos la clase HolaTest.java. Si tenemos todo correctamente implementado (tanto en el proyecto cliente como en el proyecto servidor), el resultado debería ser el siguiente.
✅ Con el proceso indicado en este artículo (y con el especificado en el artículo en el que contábamos cómo se creaba un servicio SOAP en el lado del servidor) ya tenemos una idea global de cuáles son los pasos que habría que seguir para elaborar un webservice básico. Obviamente, esto es sólo el esqueleto de un webservice porque ya sabemos que se le pueden añadir multitud de anotaciones adicionales que todavía no hemos visto. Eso ya lo dejamos para futuros post.
Pues nada, eso es todo lo que había que comentar en relación con este tema. Espero que el proceso os haya quedado más o menos claro, porque la verdad es que puede llegar a resultar un poco enrevesado para el que se acerca por primera vez al mundo SOAP. Si tenéis cualquier duda, ya sabéis que podéis preguntarme aquí abajo.
Saludos.
Comentarios
Publicar un comentario