Servicio SOAP básico I. Servidor

La prueba de concepto esta vez es crear un servicio SOAP muy básico utilizando únicamente lo proporcionado por la JVM.
Si bien lo normal en un proyecto sería utilizar unas librerias especializadas como CXF esto nos permite crear un servicio encapsulado en un ejecutable de 3Kb.
El entorno es jdk1.8, pero debería funcionar en cualquier jre igual o superior al 1.6 y aunque yo lo he desarrollado con maven es de tal simplicidad que no aporta nada utilizarlo y el ide es eclipse mars. Pero insisto en la idea de que es tan simple que aparte del jdk cualquier entorno es válido.
La visión general del proyecto son dos clases de menos de 15 lineas ( incluidos los import). Una primera que es la implementación del servicio y una segunda clase que contiene el main y publica el servicio. Es un proyecto simple que crea un standalone.
El servicio:
package es.sinjava.servidor;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class Servicio {

    public String responde(String name) {
        System.out.println("Recibido "+ name);
        return "Hola desde mi servicio " + name.toUpperCase();
    }
}
Obviament el"caldo gordo" está en las anotaciones. El proceso que realiza el método responde es código "foo" sin ningún misterio.

Y la clase que lo publica:
package es.sinjava.servidor;

import javax.xml.ws.Endpoint;

public class App {
    public static void main(String[] args) {
        String endpointURL = "http://localhost:8888/hola";
        Endpoint.create(new Servicio()).publish(endpointURL);
        System.out.println("Service Started en " + endpointURL);
    }
}
Lo que hace el main tiene poco misterio, crea un endpoint con el servicio "Servicio" y lo publica en un determinado endpoint. En una configuración tan minimalista vamos a jugar con los nombres que les asigna por defecto; para una prueba de concepto nos vale.
Si lanzamos el main veremos que despliega el servicio en 650 milisegundas ( en mi máquina). Estamos lanzando un main, no necesitamos un war desplegado en un tomcat.

Vamos a pedirle el wsdl que tiene cualquier servicio SOAP en :
http://localhost:8888/hola?wsdl

Wow, obtenemos esto en nuestro navegador:
<definitions targetNamespace="http://servidor.sinjava.es/"
    name="ServicioService">
    <types />
    <message name="responde">
        <part name="arg0" type="xsd:string" />
    </message>
    <message name="respondeResponse">
        <part name="return" type="xsd:string" />
    </message>
    <portType name="Servicio">
        <operation name="responde">
            <input wsam:Action="http://servidor.sinjava.es/Servicio/respondeRequest"
                message="tns:responde" />
            <output wsam:Action="http://servidor.sinjava.es/Servicio/respondeResponse"
                message="tns:respondeResponse" />
        </operation>
    </portType>
    <binding name="ServicioPortBinding" type="tns:Servicio">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
            style="rpc" />
        <operation name="responde">
            <soap:operation soapAction="" />
            <input>
                <soap:body use="literal" namespace="http://servidor.sinjava.es/" />
            </input>
            <output>
                <soap:body use="literal" namespace="http://servidor.sinjava.es/" />
            </output>
        </operation>
    </binding>
    <service name="ServicioService">
        <port name="ServicioPort" binding="tns:ServicioPortBinding">
            <soap:address location="http://localhost:8888/hola" />
        </port>
    </service>
</definitions>

Que es un wsdl super sencillo, para lo que nos podemos encontrar por ahí. Nos permite de forma más o menos clara identificar las partes importantes: el service name, el port name, los input y los output, etc. En un servicio con 50 métodos, que pasan 80 tipos de objetos distintos, con un wsdl de 3000 lineas se hace un poco duro seguirlo.
En la siguiente entrega veremos como consumir dichos servicios SOAP desde una aplicación standalone, sin ninguna librería aparte de las que nos proporciona java (1.6 o superior).Dada la sencillez del servicio levantado  crearemos "a mano" el cliente. En casos más complejos se utilizan diversas herramientas: wsimport, soapui, eclipse, wsdl2java, un plugin de maven ( que yo recuerde ahora) y seguro que hay alguna más para hacernos lo aburrido.
En  cualquiera de los casos esto es una prueba de concepto con interés practicamente académico

El cliente para este servicio se crea en la siguiente entrada

Comentarios