• No se han encontrado resultados

4 SERVICIOS WEB XML. 4.1 Introducción Evolución de los Servicios Web. 4. Servicios Web XML

N/A
N/A
Protected

Academic year: 2021

Share "4 SERVICIOS WEB XML. 4.1 Introducción Evolución de los Servicios Web. 4. Servicios Web XML"

Copied!
51
0
0

Texto completo

(1)

4

S

ERVICIOS

W

EB

XML

4.1

Introducción

Los Servicios Web son aplicaciones autodescriptivas que se publican, se ubican y se invocan desde cualquier lugar de la Web, con el fin de simplificar el desarrollo de complejas aplicaciones distribuidas.

Estos servicios permiten invocar funciones software a través de Internet, permitiendo que programas basados en PHP, ASP, JSP, JavaBeans y otros muchos puedan hacer peticiones a servicios que se estén ejecutando en una máquina remota y obtener la respuesta para que pueda ser integrada en una página web, un servicio WAP o cualquier otra aplicación.

El concepto de servicio web comienza a extenderse impulsado por los grandes gigantes de la informática como Sun, Oracle, HP, Microsoft e IBM. No aporta muchas novedades en cuanto a implementación, pero sí en cuanto a concepto, facilitando y simplificando el acceso a software a través de la red.

La estandarización de los servicios web se realiza a través de dos comités: OASIS (Organization for the Advancement of Structured Information Standards) y W3C (World Wide Web Consortium). Para mejorar la interoperabilidad entre distintas implementaciones de servicios web surgió la organización WS-I (Web Services Interoperatibility Organization), que ha desarrollado una serie de perfiles para definir mejor los estándares implicados.

4.1.1 Evolución de los Servicios Web

En los años 80, los protocolos de comunicación no ocupaban un lugar demasiado importante para los desarrolladores, ya que conseguir que las aplicaciones se comunicaran entre sí ya era un reto más que suficiente. Es a partir de los años 90 cuando empiezan a sugir algunas estructuras de objetos, como COM (Modelo de Objeto Componente, desarrollado por Microsoft) y CORBA (Arquitectura de negociación de petición de objetos comunes), que permitían a los programadores invocar desde una aplicación la ejecución de código binario de otra aplicación que se ejecutaba en la

(2)

Una vez que las redes locales empezaron a extenderse en los años 90 se hizo imprescindible la comunicación entre equipos. Se creó IIOP (Internet Inter-ORB Protocol) como protocolo de CORBA, DCOM (Distributed COM) como protocolo de COM y posteriormente RMI (Remote Method Invocation) para los usuarios de Java.

Mediante el uso de cualquiera de estos protocolos, una aplicación compatible puede invocar componentes que residan en otros ordenadores de la red. El problema radica en que estos protocolos no son interoperables, es decir, los usuarios que utilizan DCOM únicamente pueden llamar a servidores compatibles con DCOM. Por otro lado las soluciones anteriores tienen un requisito de simetría, de modo que no existe el paradigma cliente-servidor y por tanto es obligatoria la implantación del mismo modelo de distribución de objetos en ambos extremos de la comunicación. Esto no se puede garantizar en un entorno tan abierto como Internet.

Tras la aparición de XML a mediados de los 90 nació la posibilidad de estructurar la información de una manera uniforme y autodescriptiva, lo que dio pie a utilizar este lenguaje para aplicar un formato a los mensajes intercambiados entre sistemas. Se implementó un protocolo llamado XML-RPC que permitía llamar a procedimientos de equipos remotos sin tener en cuanta los detalles de sus sistemas operativos o entornos de lenguaje. La evolución del protocolo XML-RPC dio origen al actual SOAP (Simple Object Access Protocol).

4.1.2 Conceptos básicos

Muchas de las ideas detrás de los servicios web son asombrosamente simples y no son una novedad en el mundo de las redes e Internet:

• El proveedor de servicios web define un formato para las peticiones a un servicio y de las respuestas que generará.

• Un ordenador realiza una petición a través de una red.

• El servicio web realiza la acción solicitada y devuelve la respuesta

Esta acción puede consistir en buscar un valor actual de la bolsa, encontrar el mejor precio para un producto determinado, guardar una reunión en una agenda, traducir un fragmento de texto a cualquier lenguaje o validar el número de una tarjeta de crédito.

(3)

La razón del repentino crecimiento de los servicios web es la incorporación de protocolos estándar para invocar servicios y transmitir datos, como son SOAP y WSDL, ambos basados en XML.

4.2 XML

4.2.1 Introducción

XML es un Lenguaje de Etiquetado Extensible muy simple y a la vez estricto, que juega un papel fundamental en el intercambio de una gran variedad de datos. Es un lenguaje que puede parecer muy similar a HTML pero su función principal es describir y estructurar datos y no mostrarlos como es el caso de HTML. XML permite la lectura de datos a través de diferentes aplicaciones. En definitiva, sirve para estructurar, almacenar e intercambiar información.

La especificación XML define un procedimiento estándar para añadir etiquetas (también llamadas marcas) a los documentos; de hecho XML es un meta-lenguaje para definir lenguajes de marcas. En otras palabras, XML ofrece unas reglas para definir etiquetas y relaciones estructurales entre ellas. Al no haber etiquetas predefinidas no existe una semántica a priori; toda la semántica de un documento XML debe ser definida bien por la aplicación que lo procesa o bien por hojas de estilo.

Un documento XML tiene dos estructuras, una lógica y otra física.

• Físicamente, el documento está compuesto por unidades llamadas entidades. Cada documento comienza con una entidad documento, también llamada raíz.

• Lógicamente, el documento está compuesto de declaraciones, elementos, comentarios, referencias a caracteres e instrucciones de procesamiento, todos los cuales están indicados por una marca explícita.

Las estructuras lógica y física deben encajar de manera adecuada.

(4)

• Válidos: Además de estar bien formados, siguen una estructura y una semántica determinada por un fichero de definición (que es una especie de definición de la gramática del documento). Existen distintas formas de definir estos ficheros de definición, entre ellas DTD y XML Schema.

4.2.2 Reglas sintácticas

A continuación se expone un ejemplo muy simple de un archivo XML. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<Alumno>

<nombre>Fernando Jaime</nombre> <apellido>Pérez Borrero</apellido> <direccion>C\Gardenia 15</direccion> </Alumno>

En la primera línea se indica que lo que la sigue es XML. Puede tener varios atributos (los campos que van dentro de la declaración), algunos obligatorios y otros no:

• version: indica la versión de XML usada en el documento. La versión actual es la 1.0. Su uso es obligatorio, a no ser que sea un documento externo a otro que ya lo incluía.

• encoding: es la forma en que se ha codificado el documento. Por defecto es UTF-8, aunque podrían utilizarse otras, como UTF-16, US-ASCII, ISO-8859-1, etc. No es obligatorio salvo que sea un documento externo a otro principal.

• standalone: indica si el documento va acompañado de un DTD (standalone=”no”), o no lo necesita (standalone=”yes”); en principio no hay por qué ponerlo, porque más adelante se indica el DTD si se necesita.

En cuanto a la sintaxis del documento se han de resaltar las siguientes reglas:

• Los documentos XML son sensibles a mayúsculas, esto es, en ellos se diferencia las mayúsculas de las minúsculas. Por ello <alumno> sería una etiqueta diferente a <Alumno>.

• Todos los espacios y retornos de carro se tienen en cuenta (dentro de las etiquetas, en los elementos).

(5)

• Hay algunos caracteres especiales reservados, que forman parte de la sintaxis de XML: <, >, &, " y '. En su lugar cuando queramos representarlos deberemos usar las entidades &lt; , &gt; , &amp; , &quot; y &apos; respectivamente.

• Los valores de los atributos de todas las etiquetas deben ir siempre entrecomillados. Son válidas las dobles comillas (") y la comilla simple (').

Observando el contenido del ejemplo se puede diferenciar entre elementos y etiquetas: los elementos son las entidades en sí, lo que tiene contenido, mientras que las etiquetas sólo describen a los elementos. Un documento XML está compuesto por elementos, y en su sintaxis éstos se nombran mediante etiquetas.

Hay dos tipos de elementos: los vacíos y los no vacíos. Hay varias consideraciones importantes a tener en cuenta al respecto:

• Toda etiqueta no vacía debe tener una etiqueta de cerrado: <etiqueta> debe tener su correspondiente </etiqueta>

• Todos los elementos deben estar perfectamente anidados, es decir, las etiquetas deben ser cerradas en orden inverso al que se abrieron.

<Alumno><nombre>Fernando Jaime</Alumno></nombre> -- > INCORRECTO

<Alumno><nombre>Fernando Jaime</nombre></Alumno> -- > CORRECTO

• Los elementos vacíos son aquellos que no tienen contenido dentro del documento. Un ejemplo en HTML son los saltos de línea (<br>). La sintaxis correcta para estos elementos implica que la etiqueta tenga siempre esta forma: <etiqueta/>.

4.2.3 DTD (Definición de Tipos de Documentos)

Un DTD no es más que un conjunto de definiciones de los elementos que puede incluir un documento XML, de la forma en que deben hacerlo (qué elementos van dentro de otros) y los atributos que se les puede dar.

(6)

• Incluir dentro del documento una referencia al documento DTD en forma de URI (Universal Resource Identifier, o identificador universal de recursos) mediante la siguiente sintaxis:

<!DOCTYPE Alumno SYSTEM "http://www.esi.us.es/~fprieto/DTD/Alumno.dtd >

En este caso la palabra SYSTEM indica que el DTD se obtendrá a partir de un elemento externo al documento e indicado por el URI que lo sigue.

• O bien incluir dentro del propio documento el DTD de este modo: <?xml version="1.0"?>

<!DOCTYPE Alumno [

<!ELEMENT Alumno (nombre+, apellido+, direccion+, foto?)> <!ELEMENT nombre (#PCDATA)>

<!ATTLIST nombre sexo (masculino|femenino) #IMPLIED> <!ELEMENT apellido (#PCDATA)>

<!ELEMENT direccion (#PCDATA)> <!ELEMENT foto EMPTY>]>

<Alumno>

<nombre>Fernando Jaime</nombre> <apellido>Pérez Borrero</apellido> <direccion>C\Lagunilla 15</direccion> </ficha>

La forma de incluir el DTD directamente como en este ejemplo pasa por añadir a la declaración <!DOCTYPE y después del nombre del nombre del tipo de documento, en vez de la URI del DTD, el propio DTD entre los símbolos '[' y ']'. Todo lo que hay entre ellos será considerado parte del DTD.

En cuanto a la definición de los elementos, es bastante intuitiva: después de la cláusula <!ELEMENT se incluye el nombre del elemento (el que luego se indicará en la etiqueta), y después diferentes opciones en función del elemento:

• Entre paréntesis, si el elemento es no vacío, se indica el contenido que puede tener el elemento: la lista de elementos hijos o que descienden de él si los tiene, separados por comas; o el tipo de contenido, normalmente #PCDATA, indicando datos de tipo texto, que son los más habituales.

(7)

A la hora de indicar los elementos descendientes (los que están entre paréntesis) vemos que van seguidos de unos caracteres especiales: '+', '*', '?' y '|'. Sirven para indicar qué tipo de uso se permite hacer de esos elementos dentro del documento:

• + : uso obligatorio y múltiple; permite uno o más elementos de ese tipo dentro del elemento padre, pero como mínimo uno.

• * : opcional y múltiple; puede no haber ninguna ocurrencia, una o varias.

• ? : opcional y singular; puede no haber ninguno o como mucho uno.

• | : equivale a un OR, es decir, da la opción de usar un elemento de entre los que forman la expresión, y solo uno.

De este modo, si por ejemplo encontramos en un DTD la siguiente declaración: <!ELEMENT Alumno (nombre+, apellido+, direccion*, foto?,

telefono*|fax*)>

Indica que elemento Alumno puede contener los siguientes elementos: un nombre y un apellido como mínimo, pero puede tener más de uno de cada; opcionalmente puede incluirse una o varias direcciones, pero no es obligatorio; opcionalmente también se puede incluir una única foto; y por fin, pueden incluirse, aunque no es obligatorio en ninguno de los dos casos, uno o más teléfonos o uno o más números de fax.

4.2.4 XML Schema

XML Schema es algo similar a un DTD, es decir, que define qué elementos puede contener un documento XML, cómo están organizados, y qué atributos y de qué tipo pueden tener sus elementos.

Las ventajas de XML Schema con respecto a los DTDs son:

(8)

• Son extensibles.

Por ejemplo, XML Schema permite definir el tipo del contenido de un elemento o de un atributo, y especificar si debe ser un número entero, o una cadena de texto, o una fecha, etc. Los DTDs no nos permiten llegar a tal grado de concreción.

Veamos un ejemplo de un documento XML, y su Schema correspondiente: <documento xmlns="x-schema:personaSchema.xml">

<persona id="Fernando Jaime">

<nombre>Fernando Jaime Pérez Borrero</nombre> </persona>

</documento>

Como se puede ver en el documento XML anterior, se hace referencia a un espacio de nombres llamado "x-schema:personaSchema.xml". Es decir, le estamos diciendo al analizador sintáctico XML que valide el documento contra el Schema "personaSchema.xml".

El Schema sería algo parecido a esto:

<Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">

<AttributeType name='id' dt:type='string' required='yes'/> <ElementType name='nombre' content='textOnly'/>

<ElementType name='persona' content='mixed'> <attribute type='id'/>

<element type='nombre'/> </ElementType>

<ElementType name='documento' content='eltOnly'> <element type='persona'/>

</ElementType> </Schema>

El primer elemento del Schema define dos espacios de nombres. El primero, xml-data,le dice al analizador que esto es un Schema y no otro documento XML cualquiera. El segundo, datatypes, nos permite definir el tipo de elementos y atributos utilizando el prefijo dt.

En la siguiente tabla se muestra el significado de cada uno de las etiquetas contenidas en el XML Schema.

(9)

Nombre Significado

ElementType Define el tipo y contenido de un elemento, incluyendo los sub-elementos que pueda contener.

AttributeType Asigna un tipo y condiciones a un atributo.

Attribute Declara que un atributo previamente definido por AttributeType puede aparecer como atributo de un elemento determinado.

Element Declara que un elemento previamente definido por ElementType puede aparecer como contenido de otro elemento.

Tabla 4.1: Significado de las etiquetas contenidas en el XML Schema

Es necesario empezar el Schema definiendo los elementos más profundamente anidados dentro de la estructura jerárquica de elementos del documento XML. Las declaraciones de tipo ElementType y AttributeType deben preceder a las declaraciones de contenido Element y Attribute correspondientes.

4.2.5 Espacios de nombres XML

Los XML Namespaces (Espacios de nombres XML) proporcionan un método para evitar conflictos en los nombres de los elementos. Como los elementos en XML no están predefinidos, podría ocurrir un conflicto de nombres cuando dos elementos diferentes usan los mismos nombres de elementos

(10)

<tr>

<td>Apples</td> <td>Bananas</td> </tr>

</table>

Y el documento que viene a continuación lleva información sobre una mesa: <table>

<name>African Coffee Table</name> <width>80</width>

<length>120</length> </table>

Si estos dos documentos se unieran en uno solo, habría un conflicto en los nombres de elementos, ya que cada uno contiene un elemento <table> diferente con distinto contenido y definición.

Una forma de resolver el conflicto es usando un prefijo que se incluiría dentro de cada etiqueta, precediendo al nombre:

Para el caso de la tabla utilizaríamos el prefijo h: <h:table> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table>

Y para el caso de la mesa utilizaríamos el prefijo f: <f:table>

<f:name>African Coffee Table</f:name> <f:width>80</f:width>

<f:length>120</f:length> </f:table>

Ahora no habrá conflictos de nombres porque los dos documentos usan un nombre diferente para su elemento <table>.

Según la especificación, las etiquetas deben ser Namespaces identificados por un URI (Uniform Resource Identifier). Este Identificador de Recursos Uniforme es un método que combina URNs y URLs, y que sirve para identificar de forma universal

(11)

recursos de todo tipo existentes en la World Wide Web. Para asociar una etiqueta con un URI se utiliza el atributo xmlns.

Para el caso de la tabla utilizaríamos el espacio de nombres: http://www.w3.org/TR/html4/. <h:table xmlns:h="http://www.w3.org/TR/html4/"> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table>

Para el caso de la mesa utilizaríamos el espacio de nombres: http://www.w3schools.com/furniture.

<f:table xmlns:f="http://www.w3schools.com/furniture"> <f:name>African Coffee Table</f:name>

<f:width>80</f:width> <f:length>120</f:length> </f:table>

Cuando se define un Namespace en la etiqueta inicial de un elemento, todos los elementos hijo con el mismo prefijo se asocian al mismo espacio de nombres. Cabe resaltar que la dirección usada para identificar al Namespace no va a ser usada por el parser de XML para buscar información; su único propósito es establecer un nombre único para el prefijo.

4.2.6 Analizadores XML

Los analizadores XML son un elemento clave en los servicios web, ya que se encargan de interpretar los datos contenidos en el documento y hacerlos accesibles a la aplicación. En dispositivos con baja capacidad de procesamiento son un factor decisivo, ya que suelen tener un gran tamaño y consumen mucha memoria.

Existen tres tipos principales de analizadores XML, cada uno con sus ventajas e inconvenientes:

(12)

estructura cualquiera. Su desventaja principal es el alto consumo de memoria. El analizador DOM se basa en esta idea.

• Analizador push: Se define un conjunto de eventos que pueden aparecer en un documento XML, como pueden ser el comienzo de una etiqueta o la presencia de datos de texto, y al encontrar uno de estos eventos llama a un método que lo procese adecuadamente. El analizador SAX, usado por JSR-172, es de este tipo.

• Analizador pull: El documento XML se va recorriendo poco a poco mediante un método que pide el siguiente elemento. El analizador kXML, usado por kSOAP, es de este tipo.

4.3 SOAP

El protocolo de acceso a objetos simples (Simple Object Access Protocol, SOAP) en un estándar de W3C que define el formato de las peticiones para los servicios web.

Los mensajes SOAP son enviados entre los dos extremos de la comunicación en los llamados sobres SOAP para hacer una petición o enviar una respuesta. Estos sobres están formateados en XML y son muy fáciles de descodificar.

Actualmente un sin fin de empresas se han decantado por el desarrollo de aplicaciones que puedan trabajar sobre Internet porque permite la distribución global de la información. Las tecnologías más usadas para el desarrollo de estas aplicaciones han sido hasta hace poco CORBA, COM y EJB. Cada una proporciona un marco de trabajo basado en la activación de objetos remotos mediante la solicitud de ejecución de servicios a un servidor de aplicaciones.

Estas tecnologías han demostrado ser muy efectivas para el establecimiento de sitios Web, sin embargo presentan una serie de desventajas, como son la total incompatibilidad e interoperabilidad entre ellas y la dependencia de la plataforma sobre la que corren, así como del lenguaje de programación.

Esto ha llevado a la necesidad de considerar un nuevo modelo de computación distribuida de objetos que no sea dependiente de plataformas, modelos de desarrollo ni lenguajes de programación. Por todos estos motivos surge el concepto de SOAP (Simple Object Access Protocol).

(13)

4.3.1 Concepto de SOAP

La ventaja que aporta SOAP es la de proporcionar un mecanismo simple y ligero de intercambio de información entre dos puntos mediante documentos XML. SOAP no es más que un sencillo protocolo capaz de expresar la información mediante un modelo de empaquetado de datos modular y una serie de mecanismos de codificación de datos. Esto permite que SOAP sea utilizado en un amplio rango de servidores de aplicaciones que trabajen mediante el modelo de comunicación RPC (Remote Procedure Call).

La especificación SOAP consta de tres partes:

• El SOAP envelope, que define el marco de trabajo que determina qué se puede introducir en un mensaje, quién debería hacerlo y si esa operación es opcional u obligatoria.

• Las reglas de codificación SOAP que definen el mecanismo de serialización que será usado para encapsular en los mensajes los distintos tipos de datos.

• La representación SOAP RPC que define un modo de funcionamiento a la hora de realizar llamadas a procedimientos remotos y la obtención de sus resultados.

4.3.2 Objetivos de SOAP

A la hora de realizar el diseño de SOAP se han tenido en cuenta una serie de consideraciones con el fin de cumplir una serie de objetivos claros, objetivos que le darán el potencial que reside en SOAP y que le harán tan atractivo. Éstos son:

• Establecer un protocolo estándar de invocación a servicios remotos que esté basado en protocolos estándares de uso frecuente en Internet, como son HTTP (Hiper Text Transport Protocol) para la transmisión y XML (eXtensible Markup Language) para la codificación de los datos.

• Establecer un protocolo abierto y extensible, de modo que no existen restricciones en cuanto a datos o medio de transporte (la especificación define la manera en que los mensajes se intercambian por HTTP, pero no obliga a utilizar este protocolo).

(14)

• Independencia de plataforma hardware, lenguaje de programación e implementación del servicio Web.

El logro de estos objetivos ha hecho de SOAP un protocolo extremadamente útil, ya que el protocolo de comunicación HTTP es el empleado para la conexión sobre Internet, por lo que se garantiza que cualquier cliente con un navegador estándar pueda conectarse con un servidor remoto. Además, los datos en la transmisión se empaquetan o serializan con el lenguaje XML, que se ha convertido en algo imprescindible en el intercambio de datos ya que es capaz de salvar las incompatibilidades que existían en el resto de protocolos de representación de datos de la red.

Por otra parte, los servidores Web pueden procesar las peticiones de usuario empleando tecnologías tales como Servlets, páginas ASP (Active Server Pages) o páginas JSP (Java Server Pages).

La especificación SOAP 1.1 indica que las aplicaciones deben ser independientes del lenguaje de desarrollo, por lo que las aplicaciones cliente y servidor pueden estar escritas con HTML, DHTML, Java, Visual Basic o cualquier otra herramienta o lenguaje disponibles.

4.3.3 Un ejemplo sencillo de mensajes SOAP

Supongamos un servicio web que permita comprobar si un código postal es válido y pertenece realmente al país especificado. Este servicio web sería muy útil para asegurar la validez en un formulario de una página web. El código relativo a la petición SOAP sería: <env:Envelope xmlns:env="http://www.w3.org/2001/06/soap-envelope"> <env:Body> <m:ValidatePostcode env:encodingStyle="http://www.w3.org/2001/06/soap-encoding" xmlns:m="http://www.somesite.com/Postcode"> <Postcode> WC1A8GH </Postcode> <Country> UK </Country>

(15)

</m:ValidatePostcode> </env:Body>

</env:Envelope>

Esta petición tiene dos parámetros (postcode y country) contenidos en un elemento llamado ValidatePostcode, que sería el nombre del servicio web al que estamos haciendo la petición. El resto de los datos del sobre, como la versión de SOAP y la codificación del texto, ayuda al servicio web a procesar la petición.

La respuesta al mensaje anterior tendría el siguiente formato:

<env:Envelope xmlns:env="http://www.w3.org/2001/06/soap-envelope" > <env:Body> <m:ValidatePostcodeResponse env:encodingStyle="http://www.w3.org/2001/06/soap-encoding" xmlns:m="http://www.somesite.com/Postcode"> <Valid> Yes </Valid> </m:ValidatePostcodeResponse> </env:Body> </env:Envelope>

El elemento ValidatePostcodeResponse contesta al elemento ValidatePostcode de la petición, conteniendo un único elemento, Valid, que indica si el código postal introducido es válido o no.

4.3.4 Partes de un mensaje SOAP

Un mensaje SOAP no es más que un documento en formato XML que está constituido por tres partes bien definidas: el SOAP envelope, el SOAP header, de carácter opcional, y el SOAP body.

(16)

Figura 4.1: Partes de un mensaje SOAP

Cada uno de estos elementos se detalla a continuación:

• El envelope es el elemento más importante y de mayor jerarquía dentro del documento XML y representa al mensaje que lleva almacenado dicho documento. Todo mensaje SOAP 1.1 debe tener un elemento envelope asociado al espacio de nombres http://schemas.xmlsoap.org/soap/envelope/. Si un mensaje recibido por una aplicación SOAP contiene en este elemento un valor distinto al anterior la aplicación trataría dicho mensaje como erróneo.

• El header es un mecanismo genérico que se utiliza para añadir características adicionales al mensaje SOAP sin tener que modificar su estructura. El modo en la que se añadan cada uno de los campos dependerá exclusivamente del servicio implementado, de forma que cliente y servidor deberán estar de acuerdo con la jerarquía con la que se hayan añadido los distintos campos. De esta forma será sencillo separar entre sí los distintos datos a transmitir dentro del mensaje.

Un ejemplo de uso del header, donde se indica un cierto parámetro útil para el servicio Web que le indica como debe procesar el mensaje, sería:

<?xml version="1.0"?> <SOAP-Envelope

xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> SOAP-ENV:encodingStyle=

(17)

<SOAP-ENV:Header> <t:Transaction xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1"> 5 </t:Transaction> </SOAP-ENV:Header> <SOAP-ENV:Body> <getQuote xmlns="http://namespaces.cafeconleche.org/xmljava/ch2/"> <symbol> RHAT </symbol> </getQuote> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

• El body es un contenedor de información en el cual se almacenarán los datos que se quieran transmitir de lado a lado de la comunicación. Es aquí donde se aloja la carga útil del mensaje, de forma que para una comunicación RPC el body contendrá, entre otros, los datos referidos a la ubicación del servidor, nombre del método a invocar y parámetros necesarios. Debe depender únicamente del elemento envelope, y se sitúa inmediantamente después del elemento header en el caso de que exista. Dentro de este campo, SOAP define un elemento de uso opcional denominado Fault utilizado en los mensajes de respuesta para indicar al cliente algún error ocurrido en el servidor. Un ejemplo de uso de este nuevo elemento sería el siguiente, en el que se ha detectado un error en la aplicación que corre sobre el servidor que provoca que no opere convenientemente, por lo que se le indica al cliente:

<?xml version="1.0"?> <SOAP-ENV:Envelope

xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" > SOAP-ENV:encodingStyle=

(18)

<SOAP-ENV:Fault> <faultcode> SOAP-ENV:Server </faultcode> <faultstring> Server Error </faultstring> <detail> <e:myfaultdetails xmlns:e="Some-URI"> <message>

My application didn't work </message> <errorcode> 1001 </errorcode> </e:myfaultdetails> </detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

El atributo encodingStyle se utiliza para indicar las reglas de serialización utilizadas en el mensaje SOAP. No existe un formato de codificación por defecto, sino que existen una serie de posibles formatos a utilizar. El valor de este atributo es una lista ordenada de una o más URIs que identifican la regla o reglas de serialización que pueden ser utilizadas en el mensaje, en el orden en el que se han de aplicar. De entre todas las posibles, las más utilizadas son:http://schemas.xmlsoap.org/soap/encoding/y http://my.host/encoding/.

(19)

4.3.5 Enlaces SOAP (bindings)

Podría pensarse que SOAP consiste en un documento XML transmitido por HTTP. Lo cierto es que la norma no especifica nada respecto al medio de transporte de los mensajes. Dicho de otra manera, se pueden utilizar otros protocolos de transporte (SMTP, FTP) o cualquier otro mecanismo que se nos ocurra (ficheros de texto). En el caso de elegir HTTP como transporte de SOAP, es necesario cumplir algunas reglas básicas:

• Los mensajes se deben enviar mediante el mecanismo HTTP POST.

• El tipo de contenido debe ser text/xml.

• En la cabecera de HTTP aparecerá un nuevo encabezamiento llamado SOAPAction, cuya misión es hacer saber el propósito del mensaje SOAP a los servidores que lo reciban, sin tener que acceder al cuerpo del mensaje para obtener dicha información.

• Si el mensaje de respuesta contiene un fallo, el código del estado de la respuesta HTTP debe ser 500.

Como curiosidad cabe citar que, debido a la flexibilidad que otorga la norma en cuanto al método de transmisión, hasta una paloma mensajera podría ser el mecanismo de transporte de nuestros mensajes SOAP.

4.3.6 SOAP 1.2

En Junio de 2003 el W3C publicó la especificación SOAP 1.2. Esta nueva versión establece algunas modificaciones y aporta muchas novedades tanto en la sintaxis como en la codificación con respecto a SOAP 1.1.

La librería que implementa el protocolo SOAP en este proyecto, kSOAP2, se basa en la especificación SOAP 1.1, por ello vamos a nombrar solamente los cambios más significativos que aporta la versión 1.2:

(20)

 El atributo env:encodingStyle no debe aparecer en el envelope.

 En el elemento opcional Fault se ha sustituido client y server por Sender y Receiver. Asimismo los nombres de elementos faultcode y faultstring han sido renombrados por env:Code y env:Reason, respectivamente.

 Se define el nuevo elemento de cabecera env:NotUnderstood, utilizado cuando la información marcada con env:MustUnderstand no ha podido ser procesada.

 Los valores del atributo de la cabecera env:mustUnderstand toma los valores lógicos true o false, en lugar de 1 o 0.

• Enlace SOAP HTTP

 La cabecera Content-type debe ser application/soap+xml en lugar de text/xml.

• Codificaciones

 La sintaxis para la serialización de los arrays ha sido modificada.

 Se han eliminado valores compuestos genéricos del SOAP Data Model.

4.4 WSDL

WSDL (Web Services Definition Language) es un lenguaje basado en XML que usamos para describir un servicio web. Al publicar nuestro servicio es recomendable publicar conjuntamente un archivo WSDL que indique los métodos, dirección y estructura de éste. Cuando un cliente quiera consumir nuestro servicio bastará con que interprete el contenido del archivo WSDL, de modo que no es necesario conocer los detalles de la implementación, la plataforma o el sistema operativo sobre el que se está ejecutando.

(21)

4.4.1 Elementos de un documento WSDL

Un documento WSDL está compuesto por definiciones. Éstas definen un servicio como un conjunto de una o más redes de puntos extremos o puertos. Cada puerto está asociado a un enlace específico que se encarga de definir la manera en que un conjunto abstracto de operaciones y mensajes está enlazado a un puerto de acuerdo a un protocolo específico. Un enlace asigna un protocolo específico a un tipo de puerto. El tipo de puerto está compuesto por una o más operaciones, que representan un conjunto abstracto de posibilidades que el servicio puede llevar a cabo. Cada operación está compuesta por un conjunto de mensajes abstractos que representan los datos comunicados durante una operación. Cada mensaje contiene una o más partes de datos, que se definen como tipos.

La siguiente figura muestra de forma esquematizada la estructura que sigue un documento WSDL:                                                        → n Puerto Puerto n Operación Operación n Mensaje Mensaje n Tipo Tipo Tipo Mensaje Operación Enlace Puerto Servicio _ ... 2 _ _ ... 2 _ _ ... 2 _ _ ... 2 _ 1 _ 1 _ 1 _ 1 _ 1 _

Figura 4.2: Estructura esquematizada de un documento WSDL

Detallamos a continuación cada una de las partes:

(22)

<definitions> <documentation>

Comentarios del servicio...

</documentation> <types> Definición de tipos.... </types> <message> Definición de mensaje.... </message> <portType> Definición de operaciones.... </portType> <binding> Definición de invocación.... </binding> <service>

Ubicación del servicio....

</service> </definitions>

• <documentation>:Se utiliza para comentarios

• <types>:Define los tipos de datos contenidos en los mensajes. Ejemplo:

<types>

<complexType name="request"> <sequence>

<element name="String_1" type="string"/> <element name="String_2" type="string"/> </sequence>

(23)

</complexType> </types>

Aquí se define un tipo complejo llamado request formado por dos cadenas de caracteres, String_1 y String_2.

• <message>:Un mensaje es un contenedor de tipos de datos. Es importante saber que estos mensajes son abstractos, de manera que no hay que confundirlos con los mensajes físicos que se enviarán vía SOAP. Ejemplo:

<message name="Interface_request">

<part name="parameters" element="ns2:request"/> </message>

Aquí se define el mensaje Interface_request, cuyo parámetro es un elemento del tipo request, anteriormente definido en <types>.

• <portType>: Define las operaciones que realiza el servicio y los mensajes correspondientes. Ejemplo: <portType name="Interface"> <operation name="request"> <input message="tns:Interface_request"/> <output message="tns:Interface_requestResponse"/> </operation> </portType>

Aquí define la operación request dentro del puerto Interface cuyo mensaje de entrada es Interface_request y el de salida es Interface_requestResponse.

• <binding>: Se traduce como enlace. Define el formato y detalles del protocolo para cada operación. Ejemplo:

(24)

style="document"/> <operation name="request"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding>

Aquí se especifica que los mensajes van a seguir el estilo document/literal.

• <service>:Define la ubicación del servicio. Ejemplo:

<service name="Serverscript">

<port name="InterfacePort" binding="tns:InterfaceBinding"> <soap:address location="http://localhost:8080/server/"> </port>

</service>

Se indica que el servicio estará situado en la dirección http://localhost:8080/server.

Cabe resaltar que los elementos de un documento WSDL siguen un orden tal que el primer elemento, types, se corresponde con el nivel más bajo de la estructura representada anteriormente. De la misma forma el último elemento, service, se corresponde con el nivel más alto de la estructura jerárquica representada en la figura anterior.

4.4.2 Estilo y uso de un documento WSDL

Un archivo WSDL puede tener un estilo de llamada a procedimiento remoto (RPC) o un estilo documento (document), que afectará al formato de los datos en dicho archivo y en los mensajes SOAP que se intercambien. Será el atributo opcional style el que indicará el estilo del mensaje.

(25)

Un valor RPC indica que el mensaje utiliza una codificación de tipo RPC, cuyo objetivo es representar una llamada de método y una lista de parámetros. Un valor documentindica que el mensaje tiene un estilo de tipo documento, esto es, el mensaje representa un solo documento. En el caso de no especificar ningún estilo, se asume documentpor defecto.

Un archivo WSDL con estilo RPC tendría la siguiente forma:

<message name="myMethodRequest"> <part name="x" type="xsd:int"/> <part name="y" type="xsd:float"/> </message> <message name="empty"/> <portType name="PT"> <operation name="myMethod"> <input message="myMethodRequest"/> <output message="empty"/> </operation> </portType>

Define dos mensajes: El primero de petición, llamado myMethodRequest que recibe dos parámetros numéricos, uno entero y otro flotante. El segundo mensaje está vacío. Por último especifica la operación myMethod que recibe el mensaje myMethodRequest y devuelve el mensaje vacío empty. Este mismo ejemplo en estilo documento sería así:

<types> <schema>

<element name="xElement" type="xsd:int"/> <element name="yElement" type="xsd:float"/> </schema>

</types>

(26)

</message> <message name="empty"/> <portType name="PT"> <operation name="myMethod"> <input message="myMethodRequest"/> <output message="empty"/> </operation> </portType>

En este caso se crea un esquema con los elementos xElement e yElement de tipos entero y flotante respectivamente, y en el mensaje se especifican estos elementos en lugar de los tipos. RPC tiene la ventaja de ser más simple, pero el estilo documento es más correcto, ya que el archivo WSDL podría validarse con un analizador XML y además cumple con las especificaciones de WS-I, que promueve la interoperabilidad de servicios web.

Otro factor que afecta a los mensajes SOAP del servicio es el uso, que puede ser codificado (encoded) o literal. Un mensaje SOAP RPC/encoded tendría la siguiente forma: <soap:envelope> <soap:body> <myMethod> <x xsi:type="xsd:int"> 5 </x> <y xsi:type="xsd:float"> 5.0 </y> </myMethod> </soap:body> </soap:envelope>

(27)

Como se puede apreciar en el propio mensaje se identifica el tipo del parámetro. Esto hace al mensaje más legible, aunque en realidad no aporta información ya que el que recibe el mensaje ya sabe el tipo de los parámetros, por lo que es poco eficiente. Además no es compatible con WS-I.

Un mensaje RPC/literal sería así:

<soap:envelope> <soap:body> <myMethod> <x> 5 </x> <y> 5.0 </y> </myMethod> </soap:body> </soap:envelope>

En este caso no se envía el tipo en el mensaje lo que mejora la eficiencia, además este modo sí es compatible con WS-I. Sin embargo sigue sin poder validarse con facilidad.

Un mensaje document/literal tendría este aspecto:

<soap:envelope> <soap:body>

<xElement> 5

(28)

5.0 </yElement> </soap:body> </soap:envelope>

Este modo sí es validado fácilmente, y es compatible con WS-I siempre que el elemento soap:body tenga un sólo hijo. Esto provoca el problema de que en ocasiones es imposible distinguir a qué método remoto está dirigido el mensaje.

Para evitar los problemas de cada tipo Microsoft creó el modo document/literal wrapped, que no está definido en ningún sitio. Este modo complica mucho el archivo WSDL, que tendría el siguiente aspecto:

<types> <schema>

<element name="myMethod"> <complexType>

<sequence>

<element name="x" type="xsd:int"/> <element name="y" type="xsd:float"/> </sequence> </complexType> </element> <element name="myMethodResponse"> <complexType/> </element> </schema> </types> <message name="myMethodRequest">

<part name="parameters" element="myMethod"/> </message>

<message name="empty">

<part name="parameters" element="myMethodResponse"/> </message>

(29)

<portType name="PT"> <operation name="myMethod"> <input message="myMethodRequest"/> <output message="empty"/> </operation> </portType>

En este caso los elementos que se definen en el esquema no son los parámetros por separado, sino el conjunto de parámetros para cada mensaje. Ahora, el mensaje SOAP sí contendrá un elemento con el nombre de la operación

<soap:envelope> <soap:body> <myMethod> <x> 5 </x> <y> 5.0 </y> </myMethod> </soap:body> </soap:envelope>

La diferencia entre document y wrapped podría verse de la siguiente forma: el mensaje document se mapearía en un método así:

public void method (myMethod m);

Es decir, myMethod se considera como un objeto que contiene dos elementos. En cambio, el mensaje wrapped sería:

(30)

4.4.3 Generación del documento WSDL

La mayoría de aplicaciones de desarrollo de servicios web cuentan con una herramienta de generación automática del archivo WSDL, por ejemplo, Java2WSDL. Si ejecutamos esta aplicación desde la línea de comandos basta pasar como parámetro la clase principal de nuestro servicio y obtenemos un documento WSDL perfectamente viable. En otros casos es el propio servidor web XML el que crea automáticamente el documento WSDL a partir del servicio web desplegado.

4.4.4 Interpretación del documento WSDL

El esquema general de un servicio web se muestra en la siguiente figura:

Figura 4.3: Esquema de un servicio web

El cliente obtendría el documento WSDL, generalmente de la dirección del servicio o por medio del descubrimiento UDDI, y a partir de ahí se comunicaría con el servicio mediante mensajes SOAP. Sin embargo los dispositivos móviles no tienen la capacidad suficiente como para interpretar el documento WSDL, por lo que el esquema de servicio web para móviles es ligeramente distinto. En el caso de kSOAP se debe tener en cuenta el formato de la comunicación a nivel de código, ya que la petición SOAP se crea añadiendo los parámetros necesarios a un objeto SOAP y enviándolo luego al servidor.

La aproximación kSOAP pierde mucha flexibilidad, ya que sería necesario retocar el código en caso de pequeños cambios en el servicio. El caso de JSR-172 es diferente y sigue el siguiente esquema:

(31)

Figura 4.4: Esquema de un servicio web JSR-172

En este caso antes de incorporar la aplicación al dispositivo móvil es necesario obtener un stub a partir del documento WSDL. Una vez creado, el cliente puede llamar al servicio web a través del stub. Así el formato de la comunicación es totalmente transparente, ya que basta con invocar un método del stub para que se realice la petición y se reciba la respuesta.

4.5 UDDI

4.5.1 Concepto de UDDI

Ya tenemos desplegado nuestro Servicio Web y hemos determinado la forma de invocarlo mediante su correspondiente archivo WSDL. Lógicamente, el siguiente paso consiste en definir cómo se dará a conocer el servicio para que los clientes interesados puedan descubrirlo fácilmente y utilizarlo en sus aplicaciones. En la actualidad existe un mecanismo de descubrimiento que cumple estos requisitos: UDDI (Universal Description, Discovery and Integration), una iniciativa que permite hacer compatible el descubrimiento de servicios Web con todo tipo de tecnologías y plataformas.

Tres empresas, IBM, Microsoft y Ariba empezaron con la iniciativa UDDI. Su objetivo era definir criterios para permitir que las empresas se descubriesen las unas a

(32)

IBM, Microsoft, y SAP. Desde Enero de 2006 ninguna de estas empresas publica ya el registro global de UDDI, aunque han implementado la especificación en sus productos.

UDDI es un registro público diseñado para almacenar de forma estructurada información sobre empresas y los servicios que éstas ofrecen. A través de UDDI se puede publicar y descubrir información de una empresa y de sus servicios. Se puede utilizar sistemas taxonómicos para clasificar estos datos y poder encontrarlos posteriormente en función de la categorización. Por tanto, UDDI puede responder a todas estas preguntas:

• ¿Qué interfaces de servicios Web basadas en WSDL se han publicado y establecido para un sector determinado?

• ¿Qué empresas han escrito una implementación basada en una de estas interfaces?

• ¿Qué servicios Web, categorizados de algún modo, se ofrecen actualmente?

• ¿Qué servicios Web ofrece una empresa determinada?

• ¿Con quién se debe poner en contacto el usuario para utilizar los servicios Web de una empresa?

• ¿Cuáles son los detalles de implementación de un servicio Web concreto?

4.5.2 Datos almacenados en el registro

UDDI almacena en su registro tres tipos de datos publicados por las empresas. Se puede hacer una analogía con las guías de teléfonos, ya que se ofrecen Páginas Blancas, Páginas Amarillas y Páginas Verdes.

• Las Páginas Blancas contienen información del tipo de nombre de la empresa, información para contactar y descripción de la compañía.

• Las Páginas Amarillas contienen información que clasifica a la empresa. Esta información se basa en mecanismos de clasificación de criterios industriales como la NAICS (North American Industry Classification System) o clasificaciones geográficas.

(33)

• Las Páginas Verdes ofrecen información técnica sobre los servicios que ofrece la empresa.

4.5.3 Publicación en UDDI

La publicación en UDDI es un proceso relativamente sencillo. El primer paso consiste en determinar información básica sobre cómo definir la empresa y los servicios en UDDI. El siguiente paso, una vez determinada esta información, consiste en llevar a cabo el registro. Por último, se debe probar la entrada para asegurar que se registró correctamente y que aparece tal y como se esperaba en diferentes tipos de búsquedas y herramientas.

Partiendo del modelo de datos descrito anteriormente, la información necesaria para establecer una entrada de UDDI es la siguiente:

• Archivos WSDL que utilizan las implementaciones del servicio Web.

• Nombre de la empresa y una breve descripción de la misma en varios idiomas, si es necesario, así como los contactos principales para los servicios Web que ofrece.

• Las categorías e identificaciones adecuadas para la empresa.

• Los servicios Web que la empresa ofrece a través de UDDI.

• Las categorías adecuadas para los servicios.

Una vez recopilada esta información, se debe proceder al registro del servicio web. Actualmente cada compañía ofrece sus implementaciones de la especificación UDDI, de modo que cada una de ellas contará con un modo distinto de llevar a cabo el registro.

4.5.4 Búsqueda en UDDI

(34)

registro global, la búsqueda en UDDI implica tener que conocer nodos en los que se tenga la certeza que están publicando algún registro UDDI.

4.6 Servicios Web XML para dispositivos

móviles

El uso de SOAP para transferir datos en lugar de otras tecnologías tiene sus ventajas. En primer lugar SOAP define más de 40 tipos de datos estándar a transmitir mediante lenguaje XML. En segundo lugar permite distintos esquemas de comunicación como pueden ser llamadas a procedimientos remotos (RPC), mensajes asíncronos, multicast, etc. En último lugar, y debido a que SOAP ha ganado tanta popularidad en los servicios Web, otros muchos protocolos han enfocado sus esfuerzos a poder interactuar con éste, como es el caso de WSDL o UDDI.

4.6.1 kSOAP

kSOAP es una API SOAP diseñada para ser utilizada con Java 2 Microedition. Está basado en kXML, un parser XML de tipo pull que funciona en todas las plataformas Java, incluida J2ME. Debido a su reducido tamaño y consumo de memoria, se suele utilizar en Applets de Java en PDAs o en dispositivos móviles con soporte MIDP.

kSOAP implementa un subconjunto de la especificación SOAP 1.1. La razón para no incluir todas las características se debe a las reducidas capacidades de memoria con que cuentan los dispositivos J2ME.

4.6.1.1 SOAP parsers

Una vez que se tenga un mensaje SOAP se pueden extraer de él los distintos datos que tenga almacenados mediante un parser XML, pero será más cómodo hacerlo mediante un parser SOAP ya que, con el primero habría que extraer la información en forma de texto para después pasarla a un objeto Java que la contenga, mientras que con el parser SOAP la extracción de datos es directa. En el caso concreto de este proyecto, el parser SOAP será kSOAP.

Un parser SOAP se construye sobre un parser genérico XML al cual se le añade una serie de mecanismos específicos con los cuales realizar el “mapeo” de datos. Dicho parser SOAP es capaz de comprender los tipos de datos de la información almacenada

(35)

en el mensaje XML y de forma automática convertir texto en objetos Java, lo cual es una gran ventaja para el programador. Solo es necesario pasar los datos a un SOAP writery quedarse a la espera de la respuesta del SOAP parser.

Un ejemplo de todo esto puede verse en el siguiente mensaje SOAP en el que se ha almacenado un String que contenga el típico ejemplo “Hola Mundo”.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <message xsi:type="xsd:string"> Hola Mundo </message> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Si a este mensaje SOAP le pasamos un parser SOAP podremos obtener fácilmente el String almacenado. Supongamos que el mensaje anterior se encuentra en el String “mesg”:

ByteArrayInputStream bis =

new ByteArrayInputStream (mesg.getBytes ());

InputStreamReader reader = new InputStreamReader (bis); XmlParser xp = new XmlParser (reader);

// Se realiza un mapeo directo entre objetos Java // y elementos Soap

SoapEnvelope envelope =

new SoapEnvelope (new ClassMap (Soap.VER12)); envelope.parse (xp);

(36)

En un mensaje SOAP el atributo xsi:type especifica el tipo de dato de un elemento del mensaje, por ejemplo <midato xsi:type="xsd:int">123</midato> especifica un entero de valor 123, en cambio <midato xsi:type="xsd:string">123</midato> especifica un string de valor “123”. Es decir, kSOAP es capaz de mapear de forma directa ciertos tipos de datos Java, concretamente:

Tipo SOAP Tipo Java

xsd:int java.lang.Integer

xsd:long java.lang.Long

xsd:string java.lang.String

xsd:boolean java.lang.Boolean

Tabla 4.2: Tipos de datos Java mapeados por kSOAP

A la hora de obtener los distintos datos almacenados en un mensaje SOAP el SOAP parser lee elemento a elemento cado uno de los elementos XML que hay en el mensaje y que contienen un dato y realiza el mapeo a un objeto Java de acuerdo con las siguientes reglas:

1. Si el elemento SOAP es uno de los elementos primitivos indicados en la tabla anterior el mapeo se hace directamente.

2. Si el elemento es un tipo primitivo pero no es uno de los de la tabla anterior, lo convierte a un objeto SoapPrimitive. De éste se puede obtener o bien información mediante los métodos SoapPrimitive.getNamespace() y SoapPrimitive.getName() o bien su valor mediante el método SoapPrimitive.toString().

(37)

3. Si el elemento SOAP es un tipo complejo con varios subcampos, se convierte a un objeto de tipo KvmSerializable, concretamente al objeto SoapObject que pertenece a la interfaz KvmSerializable, y de este SoapObject se obtiene la información con los métodos SoapObject.getNamespace() y SoapObject.getName().

4.6.1.2 Composición/Descomposición de un mensaje SOAP

Supongamos que queremos montar un mensaje XML mediante los métodos que facilita kSOAP. Para ello utilizaremos una serie de métodos que montarán un mensaje que después almacenaremos en un String y que posteriormente transmitiremos por la red. Supongamos que el mensaje que queremos crear es el siguiente:

<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://www.w3.org/2001/12/soap-encoding" xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <StockOrderParameters id="o0" SOAP-ENC:root="1"> <Symbol xsi:type="xsd:string"> XYZ </Symbol> <From xsi:type="xsd:string"> Michael Yuan </From> <Shares xsi:type="xsd:int">

(38)

<Buy xsi:type="xsd:boolean"> true </Buy> <LimitPrice xsi:type="xsd:float"> 123.45 </LimitPrice> </StockOrderParameters> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Para montar todo este mensaje sencillamente tenemos que usar una serie de métodos Java proporcionados por la librería de kSOAP de forma que el código obtenido sería:

// Creamos el objetos SOAP que almacene el mensaje

SoapObject method = new SoapObject("", "StockOrderParameters"); //Añadímos cada uno de los parámetros

method.addProperty("Symbol", "XYZ");

method.addProperty("From", "Michael Yuan");

method.addProperty("Shares", new Integer (1000)); method.addProperty("Buy", new Boolean (true)); method.addProperty("LimitPrice", new SoapPrimitive

("http://www.w3.org/2001/XMLSchema", "float", "123.4")); // Ensamblamos el mensaje pasándolo por un SoapEnvelope

// Después lo almacenamos en un String

ByteArrayOutputStream bos = new ByteArrayOutputStream (); XmlWriter xw = new XmlWriter (new OutputStreamWriter (bos)); // En este caso el mapeo es directo

(39)

envelope.setBody (method); envelope.write (xw);

xw.flush (); bos.write ('\r'); bos.write ('\n');

byte [] requestData = bos.toByteArray (); String requestSOAPmesg = String (requestData);

Supongamos ahora el caso contrario, queremos extraer de un mensaje SOAP, que nos ha llegado como respuesta a una petición anterior, una serie de parámetros. Si el mensaje SOAP es el siguiente:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <result> <OrderStatus> <CustomerName xsi:type="xsd:string"> Michael Yuan </CustomerName> <Symbol xsi:type="xsd:string"> XYZ </Symbol> <Share xsi:type="xsd:int"> 1000 </Share> <Buy xsi:type="xsd:boolean"> true </Buy>

(40)

</Price> <ExecTime xsi:type="xsd:dateTime"> 2002-07-18T23:20:50.52Z </ExecTime> </OrderStatus> </result> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Para extraer de este mensaje todos los parámetros, suponiendo que todo el mensaje está en el String soapRespMesg, el código que habría que ejecutar es:

ByteArrayInputStream bis = new ByteArrayInputStream (soapRespMesg.getBytes ());

InputStreamReader reader = new InputStreamReader (bis); XmlParser xp = new XmlParser (reader);

// El mapeo en este caso es directo

SoapEnvelope envelope = new SoapEnvelope (new ClassMap (Soap.VER12)); envelope.parse (xp);

// Obtenemos la estructura de datos.

SoapObject orderStatus = (SoapObject) envelope.getResult(); // Pasamos los datos a su correspondiente tipo Java

String customerName = (String) orderStatus.getProperty ("CustomerName");

String symbol = (String) orderStatus.getProperty ("Symbol"); Integer share = (Integer) orderStatus.getProperty ("Share"); Boolean buy = (Boolean) orderStatus.getProperty ("Buy");

// Puesto que MIDP no tiene tipo "Float" no existe correspondencia // entre el tipo objeto Java y "xsd:float" tipo SOAP. Por lo que // este elemento es mapeado a un objeto "SoapPrimitive".

(41)

SoapPrimitive price = (SoapPrimitive) orderStatus.getProperty ("Price");

SoapPrimitive execTime = (SoapPrimitive) orderStatus.getProperty ("ExecTime");

4.6.1.3 Datos complejos en un mensaje SOAP

La importancia de SOAP reside en la facilidad que ofrece de poder representar datos de tipos con estructuras complejas, como pueden ser arrays, o incluso estructuras de datos que nosotros mismos definamos.

De esta forma, si queremos incluir en un mensaje SOAP un array con una serie de elementos, podemos hacerlo sin más problemas. Supongamos que un servicio Web realiza una serie de operaciones que le hemos solicitado y nos devuelve el siguiente mensaje SOAP en el que ha incluido un array:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2001/12/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:n="http://www.javaworld.com/ksoap/test"> <SOAP-ENV:Body> <result> <OrderStatus xsi:type="n:orderStatus"> <CustomerName xsi:type="xsd:string"> Michael Yuan </CustomerName> <Transactions xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="n:transaction[2]"> <Transaction xsi:type="n:transaction"> <Symbol xsi:type="xsd:string"> ABC

(42)

<Share xsi:type="xsd:int"> 500 </Share> <Buy xsi:type="xsd:boolean"> true </Buy> <Price xsi:type="xsd:float"> 43.21 </Price> </Transaction> <Transaction xsi:type="n:transaction"> <Symbol xsi:type="xsd:string"> XYZ </Symbol> <Share xsi:type="xsd:int"> 1000 </Share> <Buy xsi:type="xsd:boolean"> true </Buy> <Price xsi:type="xsd:float"> 123.45 </Price> </Transaction> </Transactions> </OrderStatus> </result> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

(43)

Al recibirse este mensaje, kSOAP lee el array y lo introduce en un objeto de tipo java.util.Vector y mediante el método Vector.elementAt(i) extrae de dicho array el elemento i-ésimo de entre todos los elementos que lo componen. Dependiendo del tipo del arrayType este objeto será almacenado en un SoapObject, en un SoapPrimitive, en un tipo por defecto Java, etc. Si suponemos que todo este mensaje SOAP se encuentra dentro del String arraySoapRespMesg, el código que realizaría la extracción del array sería:

ByteArrayInputStream bis = new ByteArrayInputStream (arraySoapRespMesg.getBytes ());

InputStreamReader reader = new InputStreamReader (bis); XmlParser xp = new XmlParser (reader);

SoapEnvelope envelope = new SoapEnvelope (new ClassMap (Soap.VER12)); envelope.parse (xp);

SoapObject orderStatus = (SoapObject) envelope.getResult(); String customerName = (String) orderStatus.getProperty ("CustomerName");

Vector transactions = (Vector) orderStatus.getProperty ("Transactions");

// Primer elemento del array

SoapObject transaction0 = (SoapObject) transactions.elementAt(0); String symbol0 = (String) transaction0.getProperty ("Symbol"); Integer share0 = (Integer) transaction0.getProperty ("Share"); Boolean buy0 = (Boolean) transaction0.getProperty ("Buy"); SoapPrimitive price0 = (SoapPrimitive) transaction0.getProperty ("Price");

// Segundo elemento del array

SoapObject transaction1 = (SoapObject) transactions.elementAt(1); String symbol1 = (String) transaction1.getProperty ("Symbol"); Integer share1 = (Integer) transaction1.getProperty ("Share"); Boolean buy1 = (Boolean) transaction1.getProperty ("Buy"); SoapPrimitive price1 = (SoapPrimitive) transaction1.getProperty ("Price");

(44)

4.6.1.4 Protocolo HTTP mediante SOAP

El gran potencial que tiene SOAP a la hora de serializar datos para transmitirlos a través de una red se complementa con una funcionalidad extremadamente útil, que es el uso del protocolo HTTP de forma directa. Dicho de otra manera, no vamos a tener que controlar HTTP explícitamente sino que esta tarea se deja en manos del API que implementa SOAP.

kSOAP cuenta con la clase HttpTransport que es la que aporta la funcionalidad de envío y recepción de mensajes SOAP vía HTTP. La forma de conexión que ofrece es una llamada a procedimiento remoto (RPC), tal que el método HttpTransport.call() toma como entrada un objeto KvmSerializable, lo serializa introduciéndolo en un mensaje SOAP completo que él mismo monta, envía dicho mensaje al servicio Web cuya dirección se haya indicado y recibe el mensaje respuesta que venga de vuelta. Tras esto pasa el mensaje recibido por un parser SOAP, llama al método SoapEnvelope.getResult() para que le devuelva el objeto Java correspondiente y dé como resultado este objeto. Y todo esto de forma automática.

La forma de utilizar este método es muy sencilla, lo vemos con el siguiente ejemplo:

// Resultado de la llamada al servicio Web String result = null;

// Dato a transmitir al servicio Web int dato = 100;

// Creamos el objeto SOAP para la llamada al servicio SoapObject rpc = new SoapObject

("urn:nombre del método", "nombre del método"); // Introducimos el parámetro en el mensaje SOAP

rpc.addProperty ("dato", dato);

// Configuramos la llamada al servicio Web

HttpTransport ht = new HttpTransport("URL destino", nombre del método);

(45)

result = ht.call (rpc);

4.6.2 JSR-172

4.6.2.1 Introducción

Las APIs de servicios web (WSA) para J2ME se definen en la Java Specification Request 172 (JSR-172). Son dos paquetes independientes y opcionales, uno dedicado a la invocación de servicios remotos y otro dedicado al análisis XML. Están centrados en la CDC y las CLDC 1.0 y CLDC 1.1. La importancia de esto estriba en que la especificación JSR-172 proporciona servicios de invocación remota y análisis XML a nivel de dispositivo, evitando así que los desarrolladores de software tengan que incorporar dichas funcionalidades en sus aplicaciones.

Los servicios web en la J2ME, definidos por la JSR-172, siguen las mismas especificaciones, arquitectura y modelo de invocación que los servicios web estándar, es decir:

• SOAP 1.1 (Simple Object Access Protocol), que define el transporte y codificación de datos.

• XML 1.0, que define el lenguaje XML.

Hay una cantidad importante de especificaciones que cubren las distintas tecnologías relacionadas con servicios web, y su número continúa creciendo. Por ello la Organización para la Interoperabilidad de Servicios Web (WS-I) ha definido el WS-I Basic Profile 1.0, que establece las especificaciones mínimas y las reglas que todos los proveedores de servicios web básicos deben seguir. La especificación JSR-172 se ha desarrollado de acuerdo al WS-I Basic Profile, aunque no soporta la especificación UDDI.

4.6.2.2 Invocación remota

La WSA de JSR-172 afronta los servicios web desde el punto de vista del cliente del servicio: WSA proporciona la API de invocacion remota (JAX-RPC) y el entorno de ejecución que permite a las aplicaciones J2ME consumir servicios en la web, pero no

(46)

Esta arquitectura de alto nivel está estructurada en:

• Un cliente, el consumidor de los servicios web. Consta de una aplicación J2ME, como MIDP, un stub de 172 con las clases necesarias y la ejecución de JSR-172.

• La red: Hace referencia a la red inalámbrica y a los protocolos de comunicación. JSR-172 no impone el uso de XML en el propio dispositivo; permite otras implementaciones (siempre que sean transparentes al cliente y al servidor) para usar codificaciones más eficientes, como el uso de protocolos binarios entre el dispositivo y la pasarela inalámbrica.

• El servidor: Productor de servicios web. Es un servidor web, típicamente detrás de un firewall o una pasarela Proxy, que puede tener acceso a recursos de respaldo.

Las aplicaciones J2ME invocan servicios remotos a través de los stubs y de la ejecución de JSR-172, típicamente sobre HTTP y SOAP. Dichos stubs esconden toda la complejidad asociada a la invocación del servicio remoto, incluyendo cómo se van a codificar y decodificar los parámetros de la solicitud y la respuesta, y todo lo relacionado con la red de comunicaciones. La invocación de métodos sigue el modelo síncrono de petición-respuesta, como se ve en la figura:

Figura 4.5: Modelo de invocación de JSR-172

Para consumir un servicio web antes hay que crear stubs de invocación de servicio. Estos stubs realizan tareas como la codificación y descodificación de los valores enviados y recibidos, y actúan de interfaz de la ejecución de JSR-172 para invocar un punto de servicio remoto. Los stubs interactúan con la ejecución a través del Interfaz de Proveedor de Servicio (SPI), que abstrae los detalles de implementación y permite portabilidad de stubs entre distintas implementaciones.

(47)

Los stubs son generados usando una herramienta que lee el documento WSDL relacionado con el servicio web. Desde el punto de vista del dispositivo móvil, el documento WSDL que queremos consumir por lo general suele existir a priori, así que lo único que hay que hacer es generar los stubs JSR-172 WSA, usando una herramienta como el generador de stubs incluído en J2ME Wireless Toolkit 2.1.

Figura 4.6: Generación del stub de JSR-172

Esto genera los ficheros Java del stub y las clases necesarias. También se ocupa del mapeado del tipo de datos de WSDL a Java, como se describirá con detalle más adelante.

Una vez se han generado los stubs y las clases necesarias, y la aplicación haya sido compilada e instalada en un dispositivo compatible con JSR-172, consumir los servicios web deseados es muy sencillo, y casi transparente. La invocación de métodos remotos se hace tan sencilla como la de métodos locales.

La API de invocación remota de métodos de JSR-172 está basada en un subconjunto de JAX-RPC 1.1 (API Java para RPC basada en XML). También está desarrollada según el WS-I Basic Profile. Soporta las siguientes características:

• SOAP 1.1

• Cualquier transporteque pueda entregar mensajes SOAP, como HTTP 1.1

• La representación literal de un mensaje SOAP que represente una petición o respuesta RPC

(48)

 xsd:byte a byte o Byte.

 xsd:short a short o Short.

 xsd:int a int o Integer.

 xsd:long a long o Long.

 xsd:float a float, o Float. Para plataformas basadas en CLDC 1.0, este tipo de datos se mapea a String.

 xsd:double a double, o Double. Para plataformas basadas en CLDC 1.0, este tipo de datos se mapea a String.

 xsd:string a String.

 xsd:base64Binary a byte[].

 xsd:hexBinary a byte[].

 xsd:complexType a Sequence de tipos primitivos.

 xsd:QName a javax.xml.namespace.QName.

 Vectores de tipos primitivos y complejos (estructuras que contengan tipos primitivos y complejos) basados en el esquema de vector XML.

Las siguientes características no son soportadas:

• Mensajes SOAP con adjuntos.

• Manejadores(handlers) de mensaje SOAP.

(49)

• Puntos de servicio(productor de servicio web).

• Soporte de descubrimiento de servicios (UDDI).

La codificación en XML no es obligatoria en el dispositivo. Así se puede reducir el tráfico de la red permitiendo que las implementaciones usen más eficientemente la codificación de los datos, como un protocolo binario entre el dispositivo y la pasarela inalámbrica, siempre que dicha codificación sea transparente tanto para el productor del servicio web como para el consumidor.

Una vez se hayan generado, compilado e instalado en el dispositivo el stub y los ficheros relacionados, consumir servicios remotos es muy simple. Si no contamos la inicialización específica dede JAX-RPC e importar RemoteException, el código de una aplicación que se desarrolle para consumir servicios web parece igual que el de una aplicación que no lo use. Esta simplicidad es posible gracias a que los stubs, como ya hemos mencionado, ocultan los detalles relacionados con la invocación remota.

4.6.2.3 Análisis XML

La API de JSR-172 para el análisis XML de J2ME se basa en un subconjunto de la API JAXP 1.2 de J2SE y la API simple para análisis XML (SAX) 2.0. El hecho de que sea un subconjunto se explica por la limitada memoria disponible en los dispositivos J2ME.

JAXP para J2ME proporciona las clases, interfaces y excepciones necesarias para analizar documentos XML. Debe ser compatible con XML 1.0, y puede validar (usando DTD) o no; el analizador seguirá las reglas de validación indicadas en la especificación de XML 1.0. Esta validación es una operación que consume muchos recursos, por eso la decisión de incluirla dependerá del fabricante del dispositivo y se basará en las limitaciones de almacenamiento y procesado del dispositivo. Para saber si el analizador está validando se puede llamar al método SAXParser.isValidating().

Los analizadores de JAXP para J2ME deben soportar espacios de nombre de XML, tal y como se define en la recomendación W3C XML Namespaces 1.0, codificación UTF-8 y UTF-16, y DTDs. No están soportados, debido a las causas ya comentadas, el Modelo de Objetos de Documento (DOM) y el Lenguaje de Transformación basado en Plantillas de Estilo (XSLT).

Referencias

Documento similar

Besides the entity property definition, employed to build the middleware layer, the entities have associated other XML information employed to automatically build diverse

The tree representation obtained is used by this module to generate a set of rules (S g ) that represent the information to be translated and what structures inside the page will

Esta clase pertenece a la vista inicial de la aplicación en la que se le muestra al usuario una ventana en la que tiene que autenticarse para poder acceder a la

Como una consecuencia de la operación aislada en que se encontraban las redes de sensores en el pasado, los fabricantes desarrollaron protocolos especializados y acordes con

En el contexto de esta especificación, sólo estamos preocupados con la violación de intimidad potencial por los elementos de seguridad definidos aquí. La

Las nuevas posibilidades en el acceso, almacenamiento y utilización de la información han motivado una toma de conciencia sobre el valor de la información en el ámbito

Once studied the impact of EPR file size, we come back to section 5.2 to verify if the time required for processing this EPR file (with SOAP and the XML parser) is irrelevant with

[r]