WSIF 서비스 개발

WSIF(Web Services Invocation Framework) 서비스는 WSIF를 사용하는 웹 서비스입니다.

이 태스크 정보

WSIF 서비스를 개발하려면 웹 서비스를 개발하거나 기존 웹 서비스를 사용하고 해당 웹 서비스에 대한 WSDL(Web Services Description Language) 문서에 기반하여 WSIF 클라이언트를 개발합니다.

developerWorks® 웹 사이트의 WebSphere® Application Server 샘플에서 다운로드할 수 있는 미리 빌드된 두 개의 WSIF 샘플도 있습니다.

  • 주소록 샘플
  • 주식 시세 샘플.

사전 빌드된 샘플 사용에 대한 자세한 정보는 developerWorks 다운로드 패키지에 포함된 문서를 참조하십시오. 이 샘플은 WebSphere Application Server 버전 5에 대한 작업을 수행하도록 작성되었습니다.

WSIF 서비스를 개발하려면 다음 단계를 완료하십시오.

프로시저

  1. 웹 서비스를 구현하십시오.

    웹 서비스 도구를 사용하여 웹 서비스를 검색, 작성, 공개하십시오. Java Bean, 엔터프라이즈 Bean, URL 웹 서비스를 개발할 수 있습니다. 웹 서비스 도구를 사용하여 스켈레톤 Java 코드 및 샘플 애플리케이션을 WSDL 문서에서 작성할 수 있습니다. 예를 들어, 엔터프라이즈 Bean은 웹 서비스로 제공될 수 있으며 RMI-IIOP(Remote Method Invocation over Internet Inter-ORB Protocol)를 액세스 프로토콜로 사용할 수 있습니다. 또는 기본 Java 호출을 액세스 프로토콜로 사용하여 Java 클래스를 웹 서비스로 사용할 수 있습니다.

    [AIX Solaris HP-UX Linux Windows][z/OS]WebSphere Studio Application Developer를 사용하여 해당 StockQuote 서비스 학습서에서 설명한 대로, Java 애플리케이션에서 웹 서비스를 작성할 수 있습니다. 이 시나리오에서 사용하는 Java 애플리케이션은 주식 기호와 함께 인터넷 웹 사이트 www.xmltoday.com에서 최근 거래가를 리턴합니다. 웹 서비스 마법사를 사용하여 이름이 StockQuoteService-binding.wsdl인 바인딩 WSDL 문서와 이름이 StockQuoteService-service.wsdl인 서비스 WSDL 문서를 StockQuoteService.java Bean에서 생성합니다. 그런 다음, 웹 서버에 웹 서비스를 배치하고 웹 서비스에 대한 클라이언트 프록시를 생성하고 클라이언트 프록시를 통해 StockQuoteService에 액세스하는 샘플 애플리케이션을 생성합니다. StockQuote 웹 서비스를 테스트하고 IBM® UDDI Explorer를 사용하여 서비스를 공개한 후 IBM UDDI Test Registry에서 StockQuote 웹 서비스를 검색합니다.

    [IBM i]WDS(WebSphere Development Studio for System i®)를 사용하여 Java 애플리케이션에서 웹 서비스를 작성할 수 있습니다. 웹 서비스 마법사를 사용하여 바인딩 WSDL 문서 및 서비스 WSDL 문서를 Java Bean에서 생성합니다. 그런 다음, 웹 서버에 웹 서비스를 배치하고 웹 서비스에 대한 클라이언트 프록시를 생성하고 클라이언트 프록시를 통해 서비스에 액세스하는 샘플 애플리케이션을 생성할 수 있습니다. 서비스를 테스트하고 IBM UDDI Explorer를 사용하여 서비스를 공개한 후 IBM UDDI Test Registry에서 서비스를 검색할 수 있습니다.

  2. WSIF 클라이언트를 개발하십시오.
    다음 정보를 사용하여 WSIF 클라이언트 개발을 도울 수 있습니다.

    AddressBook 샘플은 동기 상호작용을 위해 작성되었습니다. JMS 제공자를 사용하는 경우 WSIF 클라이언트는 비동기적으로 작동해야 할 수도 있습니다. WSIF는 이런 요구사항을 만족시키는 두 가지 기본 기능을 제공합니다.

    • 요청이 (결과적인) 응답과 일치할 수 있도록 메시지에 ID를 지정하는 상관 서비스.
    • 나중에 웹 서비스에서 응답을 선택하는 응답 핸들러.
    자세한 정보는 WSIFOperation - 비동기 상호작용 참조의 내용을 참조하십시오.

예제: WSIF를 사용하여 AddressBook 샘플 웹 서비스 동적 호출

다음은 WSIF를 사용하는 AddressBook 샘플 웹 서비스의 동적 호출에 대한 예제 코드입니다.

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

        // The starting point for any dynamic invocation using wsif is a
        // WSIFServiceFactory. Create one through the newInstance
        // method.
        WSIFServiceFactory factory = WSIFServiceFactory.newInstance();

        // Once you have a factory, you can use it to create a WSIFService object
        // corresponding to the AddressBookService service in the wsdl file.
        // Note: because you only have one service defined in the wsdl file, you
        // do not have to use the namespace and name of the service and can pass
        // null instead. This also applies to the port type, although values have
        // been used in the following example for illustrative purposes.
        WSIFService service = factory.getService(
            wsdlLocation,    // location of the wsdl file
            null,            // service namespace
            null,            // service name
           "http://www.ibm.com/namespace/wsif/samples/ab", // port type namespace
            "AddressBookPT" // port type name
        );

        // The AddressBook.wsdl file contains the definitions for two complexType
        // elements within the schema element. Map these complexTypes
        // to Java classes. These mappings are used by the Apache SOAP provider
        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"));
            // You now have a WSIFService object. The next step is to create a WSIFPort
            // object for the port you want to use. The getPort(String portName) method
            // allows us to generate a WSIFPort from the port name.
        WSIFPort port = null;

        if (portName != null) {
            port = service.getPort(portName);
        }
        if (port == null) {
            // If no port name was specified, attempt to create a WSIFPort from
            // the available ports for the port type specified on the service
            port = getPortFromAvailablePortNames(service);
        }

        // Once you have a WSIFPort, you can create an operation. Execute
        // the addEntry operation and therefore attempt to create a WSIFOperation
        // corresponding to it. The addEntry operation is overloaded in the wsdl i.e.
		// there are two versions of it, each taking different parameters (parts).
		// This overloading requires that you specify the input and output message
		// names for the operation in the createOperation method so that the correct
		// operation can be resolved.
        // Because the addEntry operation has no output message, you use null for its name.
        WSIFOperation operation =
            port.createOperation("addEntry", "AddEntryWholeNameRequest", null);

        // Create messages to use in the execution of the operation. This should
        // be done by invoking the createXXXXXMessage methods on the WSIFOperation.
        WSIFMessage inputMessage = operation.createInputMessage();
        WSIFMessage outputMessage = operation.createOutputMessage();
        WSIFMessage faultMessage = operation.createFaultMessage();

        // Create a name and address to add to the addressbook
        String nameToAdd="Chris P. Bacon";
        WSIFAddress addressToAdd =
            new WSIFAddress (1,
                "The Waterfront",
                "Some City",
                "NY",
                47907,
                new WSIFPhone (765, "494", "4900"));

        // Add the name and address to the input message
        inputMessage.setObjectPart("name", nameToAdd);
        inputMessage.setObjectPart("address", addressToAdd);

        // Execute the operation, obtaining a flag to indicate its success
        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");
        }

        // Start from fresh
        operation = null;
        inputMessage = null;
        outputMessage = null;
        faultMessage = null;

        // This time you will lookup an address from the addressbook.
        // The getAddressFromName operation is not overloaded in the
        // wsdl and therefore you can specify the operation name
        // without any input or output message names.
        operation = port.createOperation("getAddressFromName");

        // Create the messages
        inputMessage = operation.createInputMessage();
        outputMessage = operation.createOutputMessage();
        faultMessage = operation.createFaultMessage();

        // Set the name to find in the addressbook
        String nameToLookup="Chris P. Bacon";
        inputMessage.setObjectPart("name", nameToLookup);

        // Execute the operation
        operationSucceeded =
            operation.executeRequestResponseOperation(
                inputMessage,
                outputMessage,
                faultMessage);

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

            // You can get the address that was found by querying the output message
            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();
    }
}

앞의 코드는 다음 샘플 메소드를 참조합니다.

    WSIFPort getPortFromAvailablePortNames(WSIFService service)
            throws WSIFException {
        String portChosen = null;
        
        // Obtain a list of the available port names for the service
        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");
        
        // An alternative way of specifying the port to use on the service
        // is to use the setPreferredPort method. Once a preferred port has
        // been set on the service, a WSIFPort can be obtained through getPort
        // (no arguments). If a preferred port has not been set and more than
        // one port is available for the port type specified in the WSIFService,
        // an exception is thrown.
        service.setPreferredPort(portChosen);
        WSIFPort port = service.getPort();
        return port;
    }

웹 서비스는 다음 클래스를 사용합니다.

WSIFAddress:

public class WSIFAddress implements Serializable {

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

    //constructors
    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 {

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

    //constructors
    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);
    }

}

다음 코드는 웹 서비스에 대응하는 WSDL 파일입니다.

<?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>

주제 유형을 표시하는 아이콘 태스크 주제



시간소인 아이콘 마지막 업데이트 날짜: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twsf_devwes
파일 이름:twsf_devwes.html