 Tutoriales
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)
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();
}
}
}
|
|
|