Un ejemplo: Calculadora Web Service

(Imagen: Rembrandt - Festín de Belshassar)

En este ejemplito vamos a utilizar la herramienta wsgen para generar los artefectos del web service antes del despliegue. Este servicio tendrá una Service Endpoint Interface (SEI) que contendrá los métodos que la Service Implementation Bean expondrá como operaciones de Web Service. Si es que no generamos la SEI explícitamente, el runtime de JAX-WS se encargará de hacerlo.

Service Implementation Bean

Esta clase contendrá sólamente dos métodos: un método de inicialización y un método que será expuesto como Web Service. Dado que vamos a generar el documento WSDL y las clases wrapper de request y response con la herramienta wsgen, hemos hecho uso extensivo de anotaciones. Así:

package com.ivan;

@WebService(
name="Calculator",
serviceName="CalculatorService",
targetNamespace="http://www.ivan.com/calculator",
wsdlLocation="CalculatorService.wsdl"
)
@SOAPBinding(
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED,
style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.Literal
)

public class Calculator{
@Resource
private WebServiceContext mWSContext;
@PostConstruct
@WebMethod (exclude=true)
public void init(){
System.out.println("Web Service initialized, service context: " + mWSContext);
}
@WebMethod(operationName="addNumber", action="urn:Add")
@ResponseWrapper(
className = "com.ivan.javax.AddResponse",
localName = "addNumbersResponse",
targetNamespace = "http://www.ivan.com/calculator"
)
@RequestWrapper(
className = "com.ivan.javax.Add",
localName = "addNumbers",
targetNamespace = "http://www.ivan.com/calculator"
)
public int add (final int intNumber1, final int intNumber2){
System.out.println("Adding "+ intNumber1 + " and " + intNumber2);
return intNumber1 + intNumber2;
}
}

La anotación @WebService le indica a JAX-WS que esta clase contiene métodos que van a ser expuestos como Web Services. Además, contiene los siguientes elementos opcionales:

  • name="Calculator"
Nombre del Web Service. En WSDL 1.1, esto se traduciría en el nombre del elemento <wsdl:portType> : <portType name= "Calculator">

  • serviceName="CalculatorService"
Nombre del Servicio para el Web Service. En WSDL 1.1, esto se traduciría en el elemento <wsdl:service>: <service name= "CalculatorService">

  • targetNamespace = "http://www.ivan.com/calculator"
Especifica el namespace para <wsdl:portType> y/o <wsdl:service> en el documento WSDL asociado.

  • wsdlLocation="CalculatorService.wsdl"
Especifica la ubicación del documento WSDL que describe al Web Service

La anotación @SOAPBinding especifica lo siguiente:

Messaging Style: style= SOAPBinding.Style.DOCUMENT
Encoding: use=SOAPBinding.Use.LITERAL
Parameter Style: parameterStyle=SOAPBinding.ParameterStyle.WRAPPED

Los valores de arriba son los valores por defecto para la anotación SOAPBinding. Nótese que el parameter Style Wrapped es necesario dado que hay más de un parámetro en el método a exponer como Web Service.

También, tenemos una variable de instancia anotada con @Resource:

@Resource private WebServiceContext mWSContext;


Que le permite a la clase del Web Service acceder al contexto del Web Service.

El primer métodos de la clase es init():

@PostConstruct
@WebMethod(exclude=true)
public void init()

La anotación @PostConstruct marca al método para que sea invocado después de realizarse la inyección de dependencia en la clase de WS, pero antes que WS entre en uso.

La anotación @WebMethod se utiliza para excluir al método init() de ser expuesto como operación de Web Service.

Finalmente, tenemos al método add(), que queremos exponer como Web Service:

@WebMethod(operationName="addNumber", action="urn:Add")
@ResponseWrapper(
className = "com.ivan.javax.AddResponse",
localName = "addNumbersResponse",
targetNamespace = "http://www.ivan.com/calculator"
)
@RequestWrapper(
className = "com.ivan.javax.Add",
localName = "addNumbers",
targetNamespace = "http://www.ivan.com/calculator"
)
public int add (final int intNumber1, final int intNumber2){


La anotación @WebMethod se utilza ahora para marcar un método para ser expuesto como operación de Web Service. Aquí se especifica:

  • operationName="addNumbers"
En WSDL 1.1, se traduce en el atributo name del elemento <wsdl:operation> en <wsdl:portType>: <operation name="addNumbers">

  • action="urn:Add"
Especifica la SOAPAction para la operación: <soap:operation soapAction="urn:Add">

Las anotaciones @ResponseWrapper y @RequestWrapper especifican lo siguiente para el request y response de la operación:

  • className = "com.ivan.javax.AddResponse"
El nombre de la clase Java que implementa el bean JAXB que será usado para almacenar la data del request/response.

  • localName= "addNumbersResponse"
El nombre del esquema XML en donde el request/response será "wrapped". Así: <xs:element name="addNumbersResponse" type="tns:addNumbersResponse">

  • targetNamespace="http://www.ivan.com/calculator"
El nombre del esquema XML en el cuál se encuentra el elemento wrapper del request/response.

Esto ya se hizo largo. En otro post la seguimos.



Publicar un comentario