====== Creación de servicios con la técnica Bottom-up ====== --- //[[pedrody@um.es|PEDRO DELGADO YARZA]] 2014/02/18 18:26// En este proceso partimos de clases Java ya creadas, a las que anotaremos con anotaciones JAX-WS 2.x para obtener a partir de ellas el WSDL del servicio web y el XSD de los datos que maneja. ===== Creación de la interfaz (SEI) del Servicio ===== El SEI (Service Endpoint Interface) es una interfaz estándar de Java que define el conjunto de métodos de Java que serán expuestos por el servicio web. Como sabemos, una interfaz también puede contener un número de propiedades y constantes a las que la clase implementadora tendrá acceso. En el caso del SEI, podemos filtrar qué métodos deseamos exponer al servicio y cuales no. Por lo tanto, un objeto SEI se corresponde a un elemento **wsdl:portType** en el WSDL. Los métodos definidos por el SEI corresponden,por tanto, a elementos **wsdl:operation** de ese portType. Para explicar esta técnica, vamos a crear un servicio muy básico, que tendrá que contener las cuatro operaciones básicas de una calculadora de enteros: * Suma * Resta * Multiplicación * División **Codificar el SEI** Empezaremos creando una interfaz en JAVA que nos describa cuales son las operaciones que va a tener el servicio.En nuestro caso lo crearemos dentro del paquete **atica.cursosoa.servicios.calculadora** Dentro del mismo crearemos la interfaz del servicio, que podemos llamar **CalculadoraSEI**. El código de la interfaz podría ser el siguiente: public interface CalculadoraSEI { public int suma(int op1,int op2); } =====Creación de la implementación del Servicio===== Una vez guardada la interfaz anterior, se implementa directamente el servicio. Para ello, en el mismo paquete anterior, podemos crear la clase **CalculadoraImpl** que implementa la interfaz anterior. Una posible implementación de este complicado servicio podría ser: public class CalculadoraImpl implements CalculadoraSEI { public int suma(int op1, int op2) { return op1 + op2; } } =====Anotar la interfaz y la implementación con JAX-WS 2.x===== Este es el punto crucial para exponer nuestra interfaz como servicio web, puesto que hasta ahora simplemente hemos creado un conjunto de clases sólo accesibles desde la propia aplicación. Para poder exponer los métodos que deseemos debemos hacer uso de las anotaciones JAX-WS 2.x, las cuales deberemos incluirlas tanto en la implementación como en la interfaz. En la clase intefaz (o SEI) se crearán anotaciones asociadas a la parte abstracta del WSDL, así como metainformación para localizar el wsdl y el namespace al que pertenecerá el WSDL generado. * Nombre del servicio * Métodos que contiene * Parámetros * ... Mientras que en la implementación se crearán anotaciones relativas a la parte concreta de los descriptores: * Binding * Transporte * ... El siguiente es un ejemplo de posible código anotado del SEI: @WebService(name="CalculadoraSEI", targetNamespace="urn:atica:cursosoa:servicios:calculadora", wsdlLocation="wsdl/CalculadoraSEI.wsdl") @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) public interface CalculadoraSEI { @WebMethod(operationName = "Suma", action = "SumaAction") @RequestWrapper(localName="SumaRequest") @WebResult(name = "SumaResponse", partName = "SumaResponsePart") public int suma(@WebParam(partName = "OperandoAPart", name = "OperandoA") int op1, @WebParam(partName = "OperandoBPart", name = "OperandoB")int op2); } En la Implementación únicamente utilizaremos la anotación **@WebService** en la que especificaremos los siguientes parámetros: * **TargetNamespace**: Espacio de nombres del WSDL que se generará (el mismo que en el SEI) * **EndpointInterface**: Clase que contiene el SEI. * **serviceName**: Nombre del Servicio. En el WSDL se corresponde con el wsdl:service. * **portName**: En el WSDL corresponde con el wsdl:port que se encuentra dentro del wsdl:service que queramos ponerle. El siguiente es un ejemplo de implementación anotada: package atica.cursosoa.servicios.calculadora; import javax.jws.WebService; @WebService(targetNamespace="urn:atica:cursosoa:servicios:calculadora", endpointInterface="org.um.atica.sei.CalculadoraSEI", serviceName="CalculadoraSEIService", portName="CalculadoraSEIPort") public class CalculadoraImpl implements CalculadoraSEI { public int suma(int op1, int op2) { return op1 + op2; } } =====Obtener el WSDL del servicio===== Una vez anotado el código, es necesario generar el descriptor del servicio WSDL, a través de la herramienta java2ws que se incluye en Fundeweb 2.0. Para ejecutar este generador debemos configurar el fichero **build.properties** situado en el proyecto principal, para despues lanzar la tarea Ant **ws.JavaToWS.generate** En el fichero build.properties debemos configurar las siguientes propiedades: * **ws.wsdl.name**: Nombre que queremos que tenga el WSDL. * **ws.sei.class**: Nombre completo (incluyendo el paquete) de la clase SEI (interfaz). ws.wsdl.name=Calculadora.wsdl ws.sei.class=org.um.atica.sei.CalculadoraSEI Tras configurar correctamente el fichero, lanzamos la tarea Ant que nos generará dentro de la carpeta build las clases Java faltantes para completar las peticiones al servicio web, así como el WSDL necesarios y los XSD que sean necesarios. {{ :fdw2.0:fundeweb2.0:gt:rest1.png |}} Una vez generados los ficheros, los copiamos en el módulo web de nuestro proyecto y casi tendremos lista la configuración del servicio. =====Registrar el servicio===== Para registrar el servicio en nuestra aplicación, debemos modificar el fichero **sun-jaxws.xml** situado en el directorio **WEB-INF** de nuestro módulo web, para añadir el punto de acceso (end-point) a nuestro servicio web. {{ :fdw2.0:fundeweb2.0:gt:top3.png |}} Un ejemplo sería el siguiente: Tras dar de alta el end-point en este fichero el servicio web estará accesible cuando despleguemos el servidor.