Creación de Webservice SOAP básico

Vamos a tratar de explicar hoy cuál es la forma más sencilla de crear un webservice de tipo SOAP desde Eclipse. Obviamente, ya sabemos que existen multitud de alternativas para llevar a cabo esta operación, así que tendremos que acotar un poco el terreno y seleccionar algunas herramientas de partida. En cualquier caso, nos vendrá bien saber cómo se crea un servicio de este tipo y ya en un futuro podremos ir modificando componentes en función del resultado que deseemos obtener.

 


Dicho lo anterior, toca concretar un poco y procedemos a enumerar las herramientas y tecnologías que vamos a usar para la creación del webservice.

  • IDE Eclipse 
  • Java versión 8
  • Proyecto Maven
  • Servidor Tomcat
  • Librería JAX-WS

 

Creación de Webservice SOAP

 

Entramos ya en materia y nos lanzamos con la creación del servicio SOAP alojado en el lado del servidor. Los pasos a seguir serían los siguientes:

 

1º) Desde Eclipse, creamos un proyecto de tipo "Dynamic Web Project". Marcamos la opción de "Generate web.xml deployment descriptor" que nos aparece durante el proceso de creación del proyecto. El resto de cosas las podemos dejar tal y como nos salgan por defecto. 

Se nos creará un proyecto con la siguiente estructura:


2º) A continuación, nos situamos sobre el proyecto y seleccionamos la opción de menú CONFIGURE - CONVERT TO MAVEN PROJECT. Nos aparecerá la ventana de "Maven POM", en la que tendremos que seleccionar el GROUP ID, esto es, el paquete raiz de nuestro proyecto (en este ejemplo, voy a indicar el paquete com.universo.soap).

Eclipse procederá a reconfigurar nuestro proyecto para que tenga estructura Maven y nos deberá quedar algo del siguiente estilo. 


3º) Editamos el fichero pom.xml y le añadimos las propiedades de Java 8. En mi caso realmente no me hacían falta, pues ya las tenía por defecto, pero quizás vosotros sí las necesitéis en vuestro proyecto. A continuación, tenemos que añadir la librería JAXWS-RT, que es la que nos permitirá implementar el webservice de este ejemplo.

El fichero pom.xml debería quedar del siguiente modo:


<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.universo.soap</groupId>

  <artifactId>WebserviceSoapApp</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <packaging>war</packaging>

 

  <properties>

    <java.version>1.8</java.version>

    <maven.compiler.target>1.8</maven.compiler.target>

    <maven.compiler.source>1.8</maven.compiler.source>

  </properties>

 

  <dependencies>

       <dependency>

           <groupId>com.sun.xml.ws</groupId>

           <artifactId>jaxws-rt</artifactId>

           <version>2.3.2</version>

       </dependency>

  </dependencies>

 

  <build>

    <plugins>

      <plugin>

        <artifactId>maven-compiler-plugin</artifactId>

        <version>3.8.1</version>

        <configuration>

          <source>1.8</source>

          <target>1.8</target>

        </configuration>

      </plugin>

      <plugin>

        <artifactId>maven-war-plugin</artifactId>

        <version>3.2.3</version>

      </plugin>

    </plugins>

  </build>

</project>


4º) A continuación, seleccionamos el proyecto y seleccionamos la opción MAVEN - UPDATE PROJECT. En la ventana de "Update Maven Project" que nos saldrá a continuación, pulsamos el botón ACEPTAR. Eclipse procederá a descargar las librerías indicadas en las dependencias de nuestro pom.xml y las dejará asociadas a nuestros proyecto.

Las librerías de nuestro "Maven Dependencies" deberían quedar algo así:

 

Como se aprecia, ya se ha descargado la librería jaxws-rt-2.3.2.jar, que es la que nos permitirá implementar el webservice de nuestro ejemplo.


5º) Nos creamos la clase servicio Hola.java dentro del paquete com.universo.soap.server. Esta clase es la que ejecutará la lógica del webservice.


package com.universo.soap.server;

 

import javax.jws.WebMethod;

import javax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

 

// http://localhost:8080/WebserviceSoapApp/ws/hola

@WebService

@SOAPBinding(style = Style.RPC)

public class Hola {

 

    @WebMethod

    public String ciao (String nombre) {

        return String.format("Ciao %s", nombre);

    }

}

 

6º) A continuación, nos creamos el fichero de configuración sun-jaxws.xml dentro de la carpeta WEB-INF de nuestro proyecto. En este fichero hay que indicar la ubicación del servicio que se debe ejecutar y el patrón de la URL en la que quedará publicado.

El contenido del xml será el siguiente:


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

<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">

  <endpoint

     name="HolaWebService"

     implementation="com.universo.soap.server.Hola"

     url-pattern="/ws/hola"/>

</endpoints>

 

7º) Llegados a este punto, hay que modificar el fichero web.xml para indicar la configuración del JAXWSServlet. Habrá que incluir los apartados de <listener>, <servlet> y <servlet-mapping>.

El contenido modificado de web.xml debería quedar algo así.

 

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"

id="WebApp_ID" version="4.0">

  <display-name>WebserviceSoapApp</display-name>

  <welcome-file-list>

    <welcome-file>index.html</welcome-file>

    <welcome-file>index.htm</welcome-file>

    <welcome-file>index.jsp</welcome-file>

    <welcome-file>default.html</welcome-file>

    <welcome-file>default.htm</welcome-file>

    <welcome-file>default.jsp</welcome-file>

  </welcome-file-list>

 

       <listener>

             <listener-class>

                    com.sun.xml.ws.transport.http.servlet.WSServletContextListener

             </listener-class>

       </listener>

 

       <servlet>

           <servlet-name>JAXWSServlet</servlet-name>

           <servlet-class>

               com.sun.xml.ws.transport.http.servlet.WSServlet

           </servlet-class>

       </servlet>

      

       <servlet-mapping>

           <servlet-name>JAXWSServlet</servlet-name>

           <url-pattern>/ws/*</url-pattern>

       </servlet-mapping>

      

</web-app>

 

8º) Tras la inclusión de todos los ficheros anteriores, el proyecto debería quedar estructurado de la siguiente forma.


 

9º) A continuación, procedemos a arrancar el Tomcat y añadimos nuestro proyecto al servidor. Si hemos creado correctamente la aplicación, no deberíamos tener problemas de arranque. 


jul 01, 2021 9:14:59 AM com.sun.xml.ws.server.MonitorBase createRoot

INFORMACIÓN: Metro monitoring rootname successfully set to: com.sun.metro:pp=/,type=WSEndpoint,name=/WebserviceSoapApp-HolaService-HolaPort

jul 01, 2021 9:15:00 AM com.sun.xml.ws.transport.http.servlet.WSServletDelegate <init>

INFORMACIÓN: WSSERVLET14: inicializando el servlet de JAX-WS

jul 01, 2021 9:15:00 AM com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextInitialized

INFORMACIÓN: WSSERVLET12: inicializando el listener de contexto de JAX-WS

jul 01, 2021 9:15:00 AM com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextInitialized

INFORMACIÓN: WSSERVLET12: inicializando el listener de contexto de JAX-WS

jul 01, 2021 9:15:00 AM org.apache.axis.utils.JavaUtils isAttachmentSupported

ADVERTENCIA: Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.

jul 01, 2021 9:15:00 AM org.apache.coyote.AbstractProtocol start

INFORMACIÓN: Starting ProtocolHandler ["http-nio-8080"]

jul 01, 2021 9:15:00 AM org.apache.catalina.startup.Catalina start

INFORMACIÓN: Server startup in [7.822] milliseconds

 

10º) De esta forma, nuestro servicio ha debido quedar publicado correctamente. Ahora debemos tener en cuenta que "WebserviceSoapApp" es el nombre de nuestro proyecto y que "/ws/hola" es el patrón URL que hemos establecido en el fichero sun-jaxws.xml. Por tanto, el endpoint en el que debemos buscar nuestro servicio será el siguiente:

http://localhost:8080/WebserviceSoapApp/ws/hola


Si ponemos dicho endpoint en un navegador, nos aparecerá la siguiente información (recordad, siempre y cuando el servicio esté correctamente publicado):


 

Ahí tendremos la información acerca del endpoint del webservice.

Punto Final Información
Nombre de Servicio\:{http://server.soap.universo.com/}HolaService
Nombre de Puerto\:{http://server.soap.universo.com/}HolaPort
Dirección\:http://localhost:8080/WebserviceSoapApp/ws/hola
WSDL\:http://localhost:8080/WebserviceSoapApp/ws/hola?wsdl
Clase de Implantación\:com.universo.soap.server.Hola

 

11º) Adicionalmente, podemos ver el contrato WSDL (formato basado en XML) de nuestro servicio SOAP accediendo al siguiente endpoint:

http://localhost:8080/WebserviceSoapApp/ws/hola?wsdl


Si ponemos dicho endpoint en un navegador, se mostrará lo siguiente:


 

El fichero WSDL es el que nos proporciona toda la información acerca de dónde está publicado nuestro servicio SOAP y con qué datos debe realizarse la invocación para obtener la respuesta esperada. En nuestro caso, el servicio es muy sencillo y de ahí la simplicidad del WSDL, pero en servicios más complejos la información del WSDL será mucho más extensa.

El contenido de nuestro WSDL es el siguiente:


<definitions targetNamespace="http://server.soap.universo.com/" name="HolaService">

<types/>

<message name="ciao">

<part name="arg0" type="xsd:string"/>

</message>

<message name="ciaoResponse">

<part name="return" type="xsd:string"/>

</message>

<portType name="Hola">

<operation name="ciao">

<input wsam:Action="http://server.soap.universo.com/Hola/ciaoRequest" message="tns:ciao"/>

<output wsam:Action="http://server.soap.universo.com/Hola/ciaoResponse" message="tns:ciaoResponse"/>

</operation>

</portType>

<binding name="HolaPortBinding" type="tns:Hola">

<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>

<operation name="ciao">

<soap:operation soapAction=""/>

<input>

<soap:body use="literal" namespace="http://server.soap.universo.com/"/>

</input>

<output>

<soap:body use="literal" namespace="http://server.soap.universo.com/"/>

</output>

</operation>

</binding>

<service name="HolaService">

<port name="HolaPort" binding="tns:HolaPortBinding">

<soap:address location="http://localhost:8080/WebserviceSoapApp/ws/hola"/>

</port>

</service>

</definitions>


Con la información ofrecida por el WSDL, ya sólo nos quedará implementar el servicio cliente (Webservice Client) que procederá a realizar la invocación de este servicio publicado en el servidor. Recordemos que aquí sólo hemos creado el servicio que ejecuta la lógica, aún nos faltaría implementar el servicio cliente que consume la lógica que hemos desarrollado aquí. Eso, para no alargar demasiado el post actual, lo veremos en la siguiente publicación del blog. 


Pues nada, eso es todo lo que había que explicar hoy en relación con los webservices de tipo SOAP. Espero que haya servido para aclarar dudas y os emplazo al siguiente artículo en el que completaremos el ejercicio con la elaboración del servicio cliente asociado al ejemplo elaborado en el post. Nos vemos en la segunda parte.

 

Saludos.


Comentarios

Entradas populares de este blog

Configurar Apache Tomcat en Eclipse

Creación de Webservice SOAP mediante Anotaciones

Componentes y Ventanas de Java Swing