Desarrollo de servicios WSIF

Un servicio WSIF (Web Services Invocation Framework) es un servicio web que utiliza WSIF.

Acerca de esta tarea

Para desarrollar un servicio WSIF, primero desarrolle el servicio web (o utilice un servicio web existente) y, a continuación, desarrolle el cliente WSIF basándose en el documento WSDL (Web Services Description Language) para ese servicio web.

Existen además dos ejemplos de WSIF precompilados disponibles que se pueden descargar de la página de ejemplos de WebSphere Application Server en el sitio web developerWorks:

  • El ejemplo AddressBook.
  • El ejemplo StockQuote.

Para obtener más información sobre cómo utilizar los ejemplos predefinidos, consulte la documentación que se incluye en el paquete de descarga de developerWorks. Tenga en cuenta que estos ejemplos se crearon para que funcionaran con WebSphere Application Server Versión 5.

Para desarrollar un servicio WSIF, complete los siguientes pasos:

Procedimiento

  1. Implemente el servicio web.

    Utilice herramientas de servicios web para descubrir, crear y publicar el servicio web. Puede desarrollar servicios Web de URL, enterprise beans y beans Java. Puede utilizar las herramientas de servicios web para crear código Java skeleton y una aplicación de ejemplo a partir un documento WSDL. Por ejemplo, puede ofrecer un enterprise bean como servicio Web y utilizar RMI/IIOP (Remote Method Invocation over Internet Inter-ORB Protocol) como protocolo de acceso. O puede utilizar una clase Java como servicio web, con invocaciones en Java nativo como protocolo de acceso.

    [AIX Solaris HP-UX Linux Windows][z/OS]Puede utilizar WebSphere Studio Application Developer para crear servicios web a partir de aplicaciones Java, como se describe en la Guía de Aprendizaje del servicio StockQuote (cotización en bolsa). La aplicación Java que utiliza en este escenario devuelve el último precio de venta del sitio Web de Internet www.xmltoday.com dado un símbolo de bolsa. Con el asistente para servicios web, puede generar un documento WSDL de enlace llamado StockQuoteService-binding.wsdl y un documento WSDL de servicio llamado StockQuoteService-service.wsdl a partir del bean StockQuoteService.java. Entonces puede desplegar el servicio web en un servidor web, generar un proxy cliente del servicio Web y generar una aplicación de ejemplo que acceda a StockQuoteService mediante el proxy cliente. Puede probar el servicio web StockQuote, publicarlo con IBM® UDDI Explorer, y descubrir el servicio Web StockQuote en el IBM UDDI Test Registry.

    [IBM i]Puede utilizar WebSphere Development Studio for System i (WDS) para crear un servicio web a partir de una aplicación Java. Con el asistente para servicios web, puede generar un documento WSDL de enlace y un documento WSDL de servicio a partir del bean Java. Entonces puede desplegar el servicio web en un servidor web, generar un proxy cliente del servicio web y generar una aplicación de ejemplo que acceda al servicio mediante el proxy cliente. Puede probar el servicio, publicarlo con IBM UDDI Explorer, y descubrir el servicio en el IBM UDDI Test Registry.

  2. Desarrolle el cliente WSIF.
    Utilice la información siguiente para ayudarle a desarrollar un cliente WSIF:

    El ejemplo AddressBook está escrito para una interacción síncrona. Si utiliza un proveedor de JMS, es posible que el cliente WSIF necesite actuar de forma asíncrona. WSIF proporciona dos características principales que cumplen este requisito:

    • Un servicio de correlación que asigna identificadores a los mensajes, de forma que se pueda hacer coincidir la solicitud con la consiguiente respuesta.
    • Un manejador de respuestas que recoge la respuesta del servicio web posteriormente.
    Para obtener más información, consulte el apartado WSIFOperation: consulta de interacciones asíncronas.

Ejemplo: uso de WSIF para invocar el servicio Web de ejemplo AddressBook dinámicamente

El siguiente código de ejemplo sirve para invocar dinámicamente el servicio web de ejemplo Addressbook mediante WSIF:

    try {
        String wsdlLocation="clients/addressbook/AddressBookSample.wsdl";

        // El punto de inicio de cualquier invocación dinámica mediante wsif es una
        // WSIFServiceFactory. Cree uno a través del método
        // newInstance.
        WSIFServiceFactory factory = WSIFServiceFactory.newInstance();

        // Una vez que tenga una fábrica, puede utilizarla para crear un objeto WSIFService
        // que se corresponda con el servicio AddressBookService en el archivo wsdl.
        // Nota: debido a que sólo tiene un servicio definido en el archivo wsdl,
        // no necesita utilizar el espacio de nombres y el nombre del servicio y puede pasar
        // null, si es necesario. Esto también se aplica al tipo de puerto, aunque los valores
        // se han usado en el ejemplo siguiente a efectos ilustrativos.
        WSIFService service = factory.getService(
            wsdlLocation,    // ubicación del archivo wsdl 
            null,            // espacio de nombres del servicio
            null,            // nombre del servicio
           "http://www.ibm.com/namespace/wsif/samples/ab", // espacio de nombres del tipo de puerto
            "AddressBookPT" // nombre del tipo de puerto
        );

        // El archivo AddressBook.wsdl contiene las definiciones para dos elementos complexType
        // dentro del elemento schema. Correlacione estos tipos complexTypes
        // con las clases Java. El proveedor de Apache SOAP utiliza estas correlaciones            
        service.mapType(
            new javax.xml.namespace.QName(
                "http://www.ibm.com/namespace/wsif/samples/ab/types",
                "address"),
            Class.forName("com.ibm.www.namespace.wsif.samples.ab.types.WSIFAddress"));
        service.mapType(
            new javax.xml.namespace.QName(
                "http://www.ibm.com/namespace/wsif/samples/ab/types",
                "phone"),
            Class.forName("com.ibm.www.namespace.wsif.samples.ab.types.WSIFPhone"));
            // Ahora tiene un objeto WSIFService. El paso siguiente consiste en crear un objeto WSIFPort
            // para el puerto que desea utilizar. El método getPort(String portName)
            // permite generar un objeto WSIFPort a partir del nombre de puerto.
        WSIFPort port = null;

        if (portName != null) {
            port = service.getPort(portName);
        }
        if (port == null) {
            // Si no se ha especificado el nombre de puerto, pruebe a crear un elemento WSIFPort a partir
            // de los puertos disponibles para el tipo de puerto especificado en el servicio.
            port = getPortFromAvailablePortNames(service);
        }

        // Una vez que tenga un WSIFPort, puede crear una operación. Ejecute
        // la operación addEntry e intente crear una WSIFOperation
        // que se corresponda con dicha operación. La operación addEntry se sobrecarga en el wsdl. 
				// Hay dos versiones de dicha operación, cada una de las cuales
adopta parámetros distintos (partes). 
				// Esta sobrecarga requiere que se especifique los nombres de mensaje de entrada y salida para la operación 
				// del método createOperation, de forma que la operación correcta 
				// se pueda resolver.
        // Debido a que la operación addEntry no tiene un mensaje de salida, debe utilizar null como nombre.
        WSIFOperation operation =
            port.createOperation("addEntry", "AddEntryWholeNameRequest", null);

        // Cree mensajes para utilizarlos durante la ejecución de la operación. Esto debe
        // hacerse invocando los métodos createXXXXXMessage en la WSIFOperation.
        WSIFMessage inputMessage = operation.createInputMessage();
        WSIFMessage outputMessage = operation.createOutputMessage();
        WSIFMessage faultMessage = operation.createFaultMessage();

        // Cree un nombre y dirección para añadirlos a la libreta de direcciones
        String nameToAdd="Chris P. Bacon";
        WSIFAddress addressToAdd = 
            new WSIFAddress (1, 
                "The Waterfront",
                "Some City",
                "NY",
                47907,
                new WSIFPhone (765, "494", "4900"));

        // Añada el nombre y la dirección al mensaje de entrada
        inputMessage.setObjectPart("name", nameToAdd);
        inputMessage.setObjectPart("address", addressToAdd);

        // Ejecute la operación, obteniendo un distintivo que indique que se ha realizado correctamente
        boolean operationSucceeded =
            operation.executeRequestResponseOperation(
                inputMessage,
                outputMessage,
                faultMessage);

        if (operationSucceeded) {
            System.out.println("Successfully added name and address to addressbook\n");
        } else {
            System.out.println("Failed to add name and address to addressbook");
        }

        // Empiece de nuevo
        operation = null;
        inputMessage = null;
        outputMessage = null;
        faultMessage = null;

        // Esta vez buscaremos una dirección de la libreta de direcciones.
        // la operación getAddressFromName no está sobrecargada en el
        // archivo wsdl y, por lo tanto, se puede especificar el nombre
        // de operación sin nombres de mensaje de entrada o salida.
        operation = port.createOperation("getAddressFromName");

        // Cree los mensajes
        inputMessage = operation.createInputMessage();
        outputMessage = operation.createOutputMessage();
        faultMessage = operation.createFaultMessage();

        // Establezca el nombre que va a buscar en la libreta de direcciones
        String nameToLookup="Chris P. Bacon";
        inputMessage.setObjectPart("name", nameToLookup);

        // Ejecute la operación
        operationSucceeded =
            operation.executeRequestResponseOperation(
                inputMessage,
                outputMessage,
                faultMessage);

        if (operationSucceeded) {
            System.out.println("Successful lookup of name '"+nameToLookup+"' in addressbook");

            // Para obtener la dirección encontrada, se puede consultar el mensaje de salida
            WSIFAddress addressFound = (WSIFAddress) outputMessage.getObjectPart("address");
            System.out.println("The address found was:");
            System.out.println(addressFound);
        } else {
            System.out.println("Failed to lookup name in addressbook");
        }

    } catch(Exception e) {
        System.out.println("An exception occurred when running the sample:");
        e.printStackTrace();
    }
}

El código anterior se refiere al método de ejemplo siguiente:

    WSIFPort getPortFromAvailablePortNames(WSIFService service)
            throws WSIFException {
        String portChosen = null;
        
        // Obtenga una lista de los nombres de puerto disponibles para el servicio
        Iterator it = service.getAvailablePortNames();
        {
            System.out.println("Available ports for the service are: ");
            while (it.hasNext()) {
                String nextPort = (String) it.next();
                if (portChosen == null)
                    portChosen = nextPort;
                System.out.println(" - " + nextPort);
            }
        }
        if (portChosen == null) {
            throw new WSIFException("No ports found for the service!");
        }
        System.out.println("Using port " + portChosen + "\n");
        
        // Una forma alternativa de especificar el puerto que se va a utilizar en el servicio
        // es utilizar el método setPreferredPort. Una vez que un puerto preferido
        // se haya establecido en el servicio, se puede obtener un WSIFPort mediante getPort
        // (sin argumentos). Si no se ha establecido un puerto preferido y más de
        // un puerto está disponible para el tipo de puerto especificado en el WSIFService,
        // se generará una excepción. 
        service.setPreferredPort(portChosen);
        WSIFPort port = service.getPort();
        return port;
    }

El servicio web utiliza las clases siguientes:

WSIFAddress:

public class WSIFAddress implements Serializable {

    //variables de instancia
    private int	streetNum;
    private java.lang.String	streetName;
    private java.lang.String	city;
    private java.lang.String	state;
    private int	zip;
    private WSIFPhone	phoneNumber;

    //constructores
    public WSIFAddress () { }

    public WSIFAddress (int streetNum, 
                        java.lang.String streetName, 
                        java.lang.String city, 
                        java.lang.String state, 
                        int zip, 
                        WSIFPhone phoneNumber) {
          this.streetNum	= streetNum;
          this.streetName	= streetName;
          this.city	= city;
          this.state	= state;
          this.zip	= zip;
          this.phoneNumber	= phoneNumber;
    }

    public int getStreetNum() {
          return streetNum;
    }

    public  void setStreetNum(int streetNum) {
          this.streetNum	= streetNum;
    }

    public java.lang.String getStreetName() {
          return streetName;
    }

    public  void setStreetName(java.lang.String streetName) {
          this.streetName	= streetName;
    }

    public java.lang.String getCity() {
          return city;
    }

    public  void setCity(java.lang.String city) {
          this.city	= city;
    }

    public java.lang.String getState() {
          return state;
    }

    public  void setState(java.lang.String state) {
          this.state	= state;
    }

    public int getZip() {
          return zip;
    }

    public  void setZip(int zip) {
          this.zip	= zip;
    }

    public WSIFPhone getPhoneNumber() {
          return phoneNumber;
    }

    public  void setPhoneNumber(WSIFPhone phoneNumber) {
          this.phoneNumber	= phoneNumber;
    }
}

WSIFPhone:

public class WSIFPhone implements Serializable {

    //variables de instancia
    private int	areaCode;
    private java.lang.String	exchange;
    private java.lang.String	number;

    //constructores
    public WSIFPhone () { }

    public WSIFPhone (int areaCode, 
                      java.lang.String exchange,  
                      java.lang.String number) {
          this.areaCode	= areaCode;
          this.exchange	= exchange;
          this.number	= number;
    }

    public int getAreaCode() {
          return areaCode;
    }

    public  void setAreaCode(int areaCode) {
          this.areaCode	= areaCode;
}

    public java.lang.String getExchange() {
          return exchange;
    }

    public  void setExchange(java.lang.String exchange) {
          this.exchange	= exchange;
    }

    public java.lang.String getNumber() {
          return number;
    }

    public  void setNumber(java.lang.String number) {
          this.number	= number;
    }
}

WSIFAddressBook:

public class WSIFAddressBook {
    private Hashtable name2AddressTable = new Hashtable();

    public WSIFAddressBook() {
    }

    public void addEntry(String name, WSIFAddress address)
    {
        name2AddressTable.put(name, address);
    }

    public void addEntry(String firstName, String lastName, WSIFAddress address)
    {
        name2AddressTable.put(firstName+" "+lastName, address);
    }

    public WSIFAddress getAddressFromName(String name)
        throws IllegalArgumentException
    {

        if (name == null)
        {
            throw new IllegalArgumentException("The name argument must not be " +
                                               "null.");
        }
        return (WSIFAddress)name2AddressTable.get(name);
    }

}

El código siguiente es el archivo WSDL correspondiente del servicio web:

<?xml version="1.0"?>

<definitions targetNamespace="http://www.ibm.com/namespace/wsif/samples/ab"
             xmlns:tns="http://www.ibm.com/namespace/wsif/samples/ab"
             xmlns:typens="http://www.ibm.com/namespace/wsif/samples/ab/types"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:format="http://schemas.xmlsoap.org/wsdl/formatbinding/"
             xmlns:java="http://schemas.xmlsoap.org/wsdl/java/"
             xmlns:ejb="http://schemas.xmlsoap.org/wsdl/ejb/"
             xmlns="http://schemas.xmlsoap.org/wsdl/">

  <types>
    <xsd:schema
      		targetNamespace="http://www.ibm.com/namespace/wsif/samples/ab/types"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        
      <xsd:complexType name="phone">
        <xsd:element name="areaCode" type="xsd:int"/>
        <xsd:element name="exchange" type="xsd:string"/>
        <xsd:element name="number" type="xsd:string"/>
      </xsd:complexType>

      <xsd:complexType name="address">
        <xsd:element name="streetNum" type="xsd:int"/>
        <xsd:element name="streetName" type="xsd:string"/>
        <xsd:element name="city" type="xsd:string"/>
        <xsd:element name="state" type="xsd:string"/>
        <xsd:element name="zip" type="xsd:int"/>
        <xsd:element name="phoneNumber" type="typens:phone"/>      
      </xsd:complexType>
      	  
    </xsd:schema>
  </types>

  <message name="AddEntryWholeNameRequestMessage">
    <part name="name" type="xsd:string"/>
    <part name="address" type="typens:address"/>
  </message>

  <message name="AddEntryFirstAndLastNamesRequestMessage">
    <part name="firstName" type="xsd:string"/>
    <part name="lastName" type="xsd:string"/>
    <part name="address" type="typens:address"/>
  </message>

  <message name="GetAddressFromNameRequestMessage">
    <part name="name" type="xsd:string"/>
  </message>

  <message name="GetAddressFromNameResponseMessage">
    <part name="address" type="typens:address"/>
  </message>

  <portType name="AddressBookPT">
    <operation name="addEntry">
      <input name="AddEntryWholeNameRequest" 
	      	      message="tns:AddEntryWholeNameRequestMessage"/>
    </operation>
    <operation name="addEntry">
      <input name="AddEntryFirstAndLastNamesRequest" 
	      	      message="tns:AddEntryFirstAndLastNamesRequestMessage"/>
    </operation>
    <operation name="getAddressFromName">
      <input name="GetAddressFromNameRequest" 
	      	      message="tns:GetAddressFromNameRequestMessage"/>
      <output name="GetAddressFromNameResponse" 
	       	       message="tns:GetAddressFromNameResponseMessage"/>
    </operation>
  </portType>

  <binding name="SOAPHttpBinding" type="tns:AddressBookPT">
    <soap:binding style="rpc"
                   transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="addEntry">
      <soap:operation soapAction=""/>
      <input name="AddEntryWholeNameRequest">
        <soap:body use="encoded"
                   namespace="http://www.ibm.com/namespace/wsif/samples/ab"
                   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
      </input>
    </operation>
    <operation name="addEntry">
      <soap:operation soapAction=""/>
      <input name="AddEntryFirstAndLastNamesRequest">
        <soap:body use="encoded"
                   namespace="http://www.ibm.com/namespace/wsif/samples/ab"
                   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
      </input>
    </operation>
    <operation name="getAddressFromName">
      <soap:operation soapAction=""/>
      <input name="GetAddressFromNameRequest">
        <soap:body use="encoded"
                   namespace="http://www.ibm.com/namespace/wsif/samples/ab"
                   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
      </input>
      <output name="GetAddressFromNameResponse">
        <soap:body use="encoded"
                   namespace="http://www.ibm.com/namespace/wsif/samples/ab"
                   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
      </output>
    </operation>
  </binding>

  <binding name="JavaBinding" type="tns:AddressBookPT">
    <java:binding/>
    <format:typeMapping encoding="Java" style="Java">
      <format:typeMap typeName="typens:address" 
             formatType="com.ibm.www.namespace.wsif.samples.ab.types.WSIFAddress"/>
      <format:typeMap typeName="xsd:string" formatType="java.lang.String"/>
    </format:typeMapping>
    <operation name="addEntry">
      <java:operation
         methodName="addEntry"
         parameterOrder="name address"
         methodType="instance"/>
      <input name="AddEntryWholeNameRequest"/>
    </operation>
    <operation name="addEntry">
      <java:operation
         methodName="addEntry"
         parameterOrder="firstName lastName address"
         methodType="instance"/>
      <input name="AddEntryFirstAndLastNamesRequest"/>
    </operation>
    <operation name="getAddressFromName">
      <java:operation
         methodName="getAddressFromName"
         parameterOrder="name"
         methodType="instance"
         returnPart="address"/>
      <input name="GetAddressFromNameRequest"/>
      <output name="GetAddressFromNameResponse"/>
    </operation>
  </binding>
  
  <binding name="EJBBinding" type="tns:AddressBookPT">
    <ejb:binding/>
    <format:typeMapping encoding="Java" style="Java">
      <format:typeMap typeName="typens:address" 
             formatType="com.ibm.www.namespace.wsif.samples.ab.types.WSIFAddress"/>
      <format:typeMap typeName="xsd:string" formatType="java.lang.String"/>
    </format:typeMapping>
    <operation name="addEntry">
      <ejb:operation
         methodName="addEntry"
         parameterOrder="name address"
         interface="remote"/>
      <input name="AddEntryWholeNameRequest"/>
    </operation>
    <operation name="addEntry">
      <ejb:operation
         methodName="addEntry"
         parameterOrder="firstName lastName address"
         interface="remote"/>
      <input name="AddEntryFirstAndLastNamesRequest"/>
    </operation>
    <operation name="getAddressFromName">
      <ejb:operation
         methodName="getAddressFromName"
         parameterOrder="name"
         interface="remote"
         returnPart="address"/>
      <input name="GetAddressFromNameRequest"/>
      <output name="GetAddressFromNameResponse"/>
    </operation>
  </binding> 
  <service name="AddressBookService">
    <port name="SOAPPort" binding="tns:SOAPHttpBinding">
      <soap:address 
	      	      location="http://myServer/wsif/samples/addressbook/soap/servlet/rpcrouter"/>
    </port>
    <port name="JavaPort" binding="tns:JavaBinding">
      <java:address className="services.addressbook.WSIFAddressBook"/>
    </port>    
    <port name="EJBPort" binding="tns:EJBBinding">
      <ejb:address className="services.addressbook.ejb.AddressBookHome"
        jndiName="ejb/samples/wsif/AddressBook"
				classLoader="services.addressbook.ejb.AddressBook.ClassLoader"/>
    </port>    
  </service>

</definitions>

Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twsf_devwes
File name: twsf_devwes.html