Artículo
|
Apuntes de XML |
Servicios web
Introducción
- Veamos una definición formal de un servicio web: "Aplicación modular, auto-contenida y auto-descriptiva que puede ser publicada, localizada e invocada a través de Internet".
- Los servicios web hacen posible la comunicación entre aplicaciones en Internet, donde conviven múltiples plataformas y aplicaciones construidas en diversos lenguajes.
- En los últimos años se han venido utilizando otras tecnologías como RMI, CORBA o DCOM, pero ninguna de ellas asegura una compatibilidad total.
- Los servicios web hacen posible esta compatibilidad al estar basados en tecnologías estándar e independientes de plataformas y lenguajes, como HTTP, WSDL, UDDI, SOAP o XML-RPC.
Terminología
Tecnologías estándar
- WSDL: Lenguaje para describir servicios web.
- UDDI: Especificación para registros de servicios web.
- SOAP: Lenguaje que especifica la forma de enviar mensajes XML a través de Internet.
- XML-RPC: Mecanismo para invocación remota de procedimientos (métodos) utilizando XML como forma de comunicación.
APIs Java
- JAXR: Acceso a directorios de servicios.
- JAXM: Envío de mensajes XML.
- JAX-RPC: Uso de XML-RPC desde Java.
JAXR
Registros
- Un registro es una infraestructura que facilita el descubrimiento de servicios web.
- Este tipo de registros se encuentran disponibles para cualquier organización, normalmente como un servicio web más.
- Existen varias especificaciones para estos registros, las más importantes:
- UDDI, desarrollada por una serie de empresas.
- ebXML, desarrollada por las organizaciones OASIS y U.N./CEFACT
Introducción a JAXR
- Es una API para Java que permite trabajar con los registros de servicios web sin preocuparnos de los detalles de los documentos XML que intervienen en las operaciones.
- Es independiente del tipo de registro concreto al que accedemos, pues se utiliza un modelo de contenido unificado.
- Permite realizar las siguientes operaciones básicas: buscar servicios web disponibles, publicar servicios web, modificar los datos de un servicio, eliminar un servicio.
Un cliente JAXR
- A continuación mostramos el código de un programa que busca servicios web en un registro a partir de una cadena de caracteres de entrada.
import javax.xml.registry.*; import javax.xml.registry.infomodel.*; import java.net.*; import java.util.*; public class JAXRQuery { public static void main(String[] args) { if (args.length != 1) { System.out.println("Usage: java " + "JAXRQuery <query-string>"); System.exit(1); } String queryString = new String(args[0]); System.out.println("Query string is " + queryString); JAXRQuery jq = new JAXRQuery(); jq.executeQuery(queryString); } public void executeQuery(String qString) { Connection connection = null; // Definir propiedades de configuración Properties props = new Properties(); props.setProperty("javax.xml.registry.queryManagerURL", "http://uddi.microsoft.com:80/inquire"); props.setProperty("javax.xml.registry.factoryClass", "com.sun.xml.registry.uddi.ConnectionFactoryImpl"); try { // Crear la conexión con las propiedades definidas ConnectionFactory factory = ConnectionFactory.newInstance(); factory.setProperties(props); connection = factory.createConnection(); // Obtener gestor de consultas RegistryService rs = connection.getRegistryService(); BusinessQueryManager bqm = rs.getBusinessQueryManager(); System.out.println("Got registry service and " + "query manager"); // Definir opciones y patrón de búsqueda Collection findQualifiers = new ArrayList(); findQualifiers.add(FindQualifier.SORT_BY_NAME_DESC); Collection namePatterns = new ArrayList(); namePatterns.add("%" + qString + "%"); // Buscar organizaciones BulkResponse response = bqm.findOrganizations(findQualifiers, namePatterns, null, null, null, null); Collection orgs = response.getCollection(); // Mostrar información de las organizaciones obtenidas Iterator orgIter = orgs.iterator(); while (orgIter.hasNext()) { Organization org = (Organization) orgIter.next(); System.out.println("Org name: " + getName(org)); System.out.println("Org description: " + getDescription(org)); System.out.println("Org key id: " + getKey(org)); // Información de contacto User pc = org.getPrimaryContact(); if (pc != null) { PersonName pcName = pc.getPersonName(); System.out.println(" Contact name: " + pcName.getFullName()); Collection phNums = pc.getTelephoneNumbers(pc.getType()); Iterator phIter = phNums.iterator(); while (phIter.hasNext()) { TelephoneNumber num = (TelephoneNumber) phIter.next(); System.out.println(" Phone number: " + num.getNumber()); } Collection eAddrs = pc.getEmailAddresses(); Iterator eaIter = eAddrs.iterator(); while (phIter.hasNext()) { System.out.println(" Email Address: " + (EmailAddress) eaIter.next()); } } // Información de los servicios Collection services = org.getServices(); Iterator svcIter = services.iterator(); while (svcIter.hasNext()) { Service svc = (Service) svcIter.next(); System.out.println(" Service name: " + getName(svc)); System.out.println(" Service description: " + getDescription(svc)); Collection serviceBindings = svc.getServiceBindings(); Iterator sbIter = serviceBindings.iterator(); while (sbIter.hasNext()) { ServiceBinding sb = (ServiceBinding) sbIter.next(); System.out.println(" Binding " + "Description: " + getDescription(sb)); System.out.println(" Access URI: " + sb.getAccessURI()); } } System.out.println(" --- "); } } catch (Exception e) { e.printStackTrace(); } finally { // Cerrar conexión if (connection != null) { try { connection.close(); } catch (JAXRException je) {} } } } private String getName(RegistryObject ro) throws JAXRException { try { return ro.getName().getValue(); } catch (NullPointerException npe) { return ""; } } private String getDescription(RegistryObject ro) throws JAXRException { try { return ro.getDescription().getValue(); } catch (NullPointerException npe) { return ""; } } private String getKey(RegistryObject ro) throws JAXRException { try { return ro.getKey().getId(); } catch (NullPointerException npe) { return ""; } } }
JAXM
Mensajes SOAP
- Un mensaje SOAP tiene la siguiente estructura:
- Parte SOAP
- Cabecera (opcional)
- Cuerpo
- Parte adjunta 1 (opcional, p. ej. texto plano)
- Parte adjunta 2 (opcional, p. ej. una imagen)
- Parte SOAP
Introducción a JAXM
- Es una API para Java que permite trabajar con mensajes SOAP sin preocuparnos de los detalles de los documentos XML que intervienen en las operaciones.
- Permite enviar mensajes de dos formas:
- Mediante una conexión punto a punto: el programa envía el mensaje directamente al destinatario, quedando bloqueado a la espera de una respuesta.
- Mediante un proveedor de mensajes: se envía el mensaje a un proveedor que será el encargado de hacerlo llegar al destinatario, sin producirse ningún bloqueo en espera de una respuesta.
Ejemplos
- El siguiente programa construye un mensaje SOAP, en el que se pregunta por el precio de cotización de una compañía, lo envía a un servicio de información de cotizaciones, y muestra el resultado obtenido:
import javax.xml.soap.*; import javax.xml.messaging.*; import java.io.*; import java.util.*; public class Request { public static void main(String[] args) { try { // Crear la conexión SOAPConnectionFactory scFactory = SOAPConnectionFactory.newInstance(); SOAPConnection con = scFactory.createConnection(); // Crear el mensaje MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); // Obtener componentes del mensaje SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody(); // Quitar cabecera header.detachNode(); // Añadir elemento para llamada Name bodyName = envelope.createName("GetLastTradePrice", "m", "http://wombat.ztrade.com"); SOAPBodyElement gltp = body.addBodyElement(bodyName); // Añadir elemento para dato de entrada Name name = envelope.createName("symbol"); SOAPElement symbol = gltp.addChildElement(name); symbol.addTextNode("SUNW"); // URL Destino URLEndpoint endpoint = new URLEndpoint( "http://wombat.ztrade.com/quotes"); // Envíar mensaje - bloqueo - obtener respuesta SOAPMessage response = con.call(message, endpoint); /* Mensaje SOAP <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" <SOAP-ENV:Body> <m:GetLastTradePrice xmlns:m= "http://wombat.ztrade.com"> <symbol>SUNW</symbol> </m:GetLastTradePrice> </SOAP-ENV:Body> </SOAP-ENV:Envelope> */ // Cerrar la conexión con.close(); // Obtener cuerpo del mensaje SOAPPart sp = response.getSOAPPart(); SOAPEnvelope se = sp.getEnvelope(); SOAPBody sb = se.getBody(); // Obtener respuesta Iterator it = sb.getChildElements(bodyName); SOAPBodyElement bodyElement = (SOAPBodyElement)it.next(); String lastPrice = bodyElement.getValue(); // Imprimir respuesta System.out.print("The last price for SUNW is "); System.out.println(lastPrice); } catch (Exception ex) { ex.printStackTrace(); } } } - El siguiente programa envía un mensaje SOAP con un nombre de compañía a un registro UDDI, y muestra los datos obtenidos del registro:
import javax.xml.soap.*; import javax.xml.messaging.*; import java.util.*; import java.io.*; public class MyUddiPing { public static void main(String[] args) { try { // Comprobar el argumento de entrada if (args.length != 1) { System.err.println("Usage: UddiPing business-name"); System.exit(1); } // Crear la conexión y el mensaje SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance(); SOAPConnection connection = scf.createConnection(); MessageFactory msgFactory = MessageFactory.newInstance(); SOAPMessage msg = msgFactory.createMessage(); // Obtener el cuerpo del mensaje SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope(); SOAPBody body = envelope.getBody(); // Añadir información de consulta SOAPBodyElement findBusiness = body.addBodyElement(envelope. createName("find_business", "", "urn:uddi-org:api")); findBusiness.addAttribute(envelope.createName("generic"), "1.0"); findBusiness.addAttribute(envelope.createName("maxRows"), "100"); SOAPElement businessName = findBusiness.addChildElement( envelope.createName("name")); businessName.addTextNode(args[0]); // URL destino URLEndpoint endpoint = new URLEndpoint ("http://www-3.ibm.com/services/uddi/testregistry/inquiryapi"); // Envíar mensaje - bloqueo - obtener respuesta SOAPMessage reply = connection.call(msg, endpoint); // Escribir mensaje de respuesta en un fichero System.out.println("Received reply from: " + endpoint); reply.writeTo(new FileOutputStream("res.xml")); // Extraer el cuerpo SOAPBody replyBody = reply.getSOAPPart().getEnvelope().getBody(); System.out.println(""); System.out.println(""); System.out.print( "Content extracted from the reply message: "); // Mostrar información Iterator iter1 = replyBody.getChildElements(); while (iter1.hasNext()) { SOAPBodyElement bodyElement = (SOAPBodyElement)iter1.next(); Iterator iter2 = bodyElement.getChildElements(); while (iter2.hasNext()) { SOAPElement child2 = (SOAPElement)iter2.next(); Iterator iter3 = child2.getChildElements(); String content = child2.getValue(); System.out.println(content); while (iter3.hasNext()) { SOAPElement child3 = (SOAPElement)iter3.next(); Iterator iter4 = child3.getChildElements(); content = child3.getValue(); System.out.println(content); while (iter4.hasNext()) { SOAPElement child4 = (SOAPElement)iter4.next(); content = child4.getValue(); System.out.println(content); } } } } // Cerrar la conexión connection.close(); } catch (Exception ex) { ex.printStackTrace(); } } }
JAX-RPC
Introducción
- Es una API para Java que permite construir servicios web y clientes para los servicios sin preocuparnos de los detalles de los documentos XML que intervienen en las operaciones.
- Las llamadas a los métodos y las respuestas se implementan mediante mensajes SOAP.
- En un servicio web, los métodos que lo constituyen se definen en un interfaz y se implementan en una clase aparte.
- En un cliente, las llamadas a los métodos se realizan mediante objetos locales que representan el método remoto (stubs).
- Un cliente escrito con JAX-RPC puede interactuar con un servicio escrito en otro lenguaje, y viceversa, pues esta tecnología se basa en una serie de estándares como HTTP, SOAP y WSDL.
Un ejemplo
- A continuación se muestra un sencillo ejemplo de servicio con un cliente que lo utiliza:
package SR; import java.rmi.Remote; import java.rmi.RemoteException; public interface SRInt extends Remote { public int suma(int a, int b) throws RemoteException; public int resta(int a, int b) throws RemoteException; } package SR; public class SRImpl implements SRInt { public int suma(int a, int b) { return a + b; } public int resta(int a, int b) { return a - b; } } package SR; public class SRClient { public static void main(String[] args) { try { SRInt_Stub stub = (SRInt_Stub)(new ServicioSRImpl().getSRInt()); stub._setTargetEndpoint(args[0]); System.out.println(stub.suma(3, 8)); System.out.println(stub.resta(23, 8)); } catch (Exception ex) { ex.printStackTrace(); } } }
Comentarios
Últimas noticias
Últimos artículos
















































