Visual Basic 6 Client for Apache SOAP Using the High Level API

The following instructions produce Visual Basic 6 client applications for the Apache SOAP stock quote sample. They use the high level API from the Microsoft SOAP Toolkit. There are instructions elsewhere for using the low level API.

The instructions in this document assume that Apache SOAP is installed according to these instructions. It is also assumed that Visual Basic 6 is installed. The version I am running is SP5. My tests were run on NT Server 4 SP 6 and Windows 2000 Server SP1.

Install SOAP Toolkit
Install Web Services Toolkit
Generate WSDL for Stock Quote
Change the Deployment Descriptor for Stock Quote
Run the Stock Quote client
Trace the Stock Quote client
Edit the Stock Quote WSDL
Trace the Stock Quote client again
Resources

Install SOAP Toolkit

  1. Download a version of the SOAP Toolkit from Microsoft. I used version 2.0 and 2.0 SP2 for these tests.
  2. Follow the instructions in the installer. I installed to j:\program files 4\MSSOAP. The installer put the run-time files in j:\program files 4\common files\MSSOAP.
  3. Note the following about the SOAP Toolkit (from the readme.txt file)
    • The SOAP client objects will run on Windows 98, Windows ME, Windows NT 4.0 Service Pack 6, Windows 2000 Service Pack 1.
    • This release requires Internet Explorer 5.0 or 5.5.
    • The SOAP Toolkit 2.0 installation will install MSXML 3.0.
Return to top.

Install Web Services Toolkit

  1. Download a version of the Web Services Toolkit from IBM alphaWorks. I used version 3.0.1 for these tests.
  2. Follow the instructions in the installer. I installed to i:\wstk-3.0.
  3. Note that an alternative is to download Axis, as the only part of the WSTK I used is the java2wsdl tool borrowed from Axis.
Return to top.

Generate WSDL for Stock Quote

Generate WSDL for the stock quote service and place a copy in the soap web application by running the following commands:

  • set WSTK_HOME=I:\wstk-3.0
  • I:\wstk-3.0\bin\java2wsdl -w all -n urn:xmltoday-delayed-quotes -l http://localhost:8080/soap/servlet/rpcrouter -o StockQuoteService.wsdl samples.stockquote.StockQuoteService
  • xcopy /y StockQuoteService.wsdl j:\jakarta-tomcat-4.0.1\webapps\soap

The WSDL generated by this is:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:xmltoday-delayed-quotes"
                  xmlns="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:impl="urn:xmltoday-delayed-quotes-impl"
                  xmlns:intf="urn:xmltoday-delayed-quotes"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <wsdl:message name="getQuoteResponse">
      <wsdl:part name="getQuoteResult" type="xsd:float"/>
   </wsdl:message>
   <wsdl:message name="getQuoteRequest">
      <wsdl:part name="arg0" type="xsd:string"/>
   </wsdl:message>
   <wsdl:portType name="StockQuoteServicePortType">
      <wsdl:operation name="getQuote">
         <wsdl:input message="intf:getQuoteRequest"/>
         <wsdl:output message="intf:getQuoteResponse"/>
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="StockQuoteServiceSoapBinding"
                 type="intf:StockQuoteServicePortType">
      <soap:binding style="rpc"
                    transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="getQuote">
         <soap:operation soapAction="" style="rpc"/>
         <wsdl:input>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                       namespace="urn:xmltoday-delayed-quotes"
                       use="encoded"/>
         </wsdl:input>
         <wsdl:output>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                       namespace="urn:xmltoday-delayed-quotes"
                       use="encoded"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="StockQuoteService">
      <wsdl:port binding="intf:StockQuoteServiceSoapBinding"
                 name="StockQuoteServicePort">
         <soap:address location="http://localhost:8080/soap/servlet/rpcrouter"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>
Return to top.

Change the Deployment Descriptor for Stock Quote

When using the high level API, the Visual Basic client will not include data type information for parameters by specifying the xsi:type attribute. Therefore, it is necessary to provide a way for Apache SOAP to know what the parameter types are in the SOAP call, so that it can determine how to deserialize the parameters, even for simple types for which Apache SOAP has built-in mappings based on xsi:type. This is done by mapping the parameter's element name to a de-serializer. The WSDL above shows a single parameter named arg0. The following instructions create a mapping for this element name. (Note that, as an alternative, one can edit the WSDL to coerce the client to include type information in an xsi:type attribute).

  1. Add an isd:mappings element to the deployment descriptor and save the file to j:\soap-2_2\samples\stockquote\DeploymentDescriptorInterop.xml. The file should look like this:
    <isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
                 id="urn:xmltoday-delayed-quotes">
      <isd:provider type="java"
                    scope="Application"
                    methods="getQuote">
        <isd:java class="samples.stockquote.StockQuoteService"/>
      </isd:provider>
      <isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener>
      <isd:mappings>
        <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
         xmlns:x="" qname="x:arg0"
         xml2JavaClassName="org.apache.soap.encoding.soapenc.StringDeserializer"/>
      </isd:mappings>    
    </isd:service>
        
  2. Run the following commands to install the new deployment descriptor:
    • j:
    • cd \soap-2_2\samples\stockquote
    • java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter undeploy urn:xmltoday-delayed-quotes
    • java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter deploy DeploymentDescriptorInterop.xml
Return to top.

Run the Stock Quote client

  1. Download the Stock Quote client source.
  2. Unzip the downloaded file.
  3. Open the project named StockQuoteClientHi in Visual Basic and run it.

The stock quote client is a simple application of the COM objects provided by the SOAP Toolkit, which heavily leverage the service description in the WSDL file. The code is as follows.

Option Explicit

Sub Main()
    Dim client As Object

    Set client = CreateObject("MSSOAP.SoapClient")

    client.mssoapinit "http://localhost:8080/soap/StockQuoteService.wsdl", _
                      "StockQuoteService", _
                      "StockQuoteServicePort"
    MsgBox client.getQuote("IBM")
End Sub
Return to top.

Trace the Stock Quote client

The TcpTunnelGui utility, included in Apache SOAP, is invaluable is seeing what characters are being sent and received by the client.

  1. Start TcpTunnelGui by running java org.apache.soap.util.net.TcpTunnelGui 81 localhost 8080
  2. In the WSDL file, change localhost:8080 to localhost:81 the one place it occurs.
  3. Run the Stock Quote client again.

The client sends the following (formatting changed for readability):

POST /soap/servlet/rpcrouter HTTP/1.1
Content-Type: text/xml; charset="UTF-8"
Host: localhost
SOAPAction: ""
Content-Length: 350

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAPSDK1:getQuote xmlns:SOAPSDK1="urn:xmltoday-delayed-quotes">
<arg0>
IBM
</arg0>
</SOAPSDK1:getQuote>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The (formatted) response from the server is:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 479
Date: Thu, 04 Apr 2002 03:07:52 GMT
Server: Apache Tomcat/4.0.1 (HTTP/1.1 Connector)
Set-Cookie: JSESSIONID=35A331A92481A1406260B343F151A040;Path=/soap

<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
                   xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getQuoteResponse xmlns:ns1="urn:xmltoday-delayed-quotes"
            SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:float">
99.96
</return>
</ns1:getQuoteResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Return to top.

Edit the Stock Quote WSDL

As an alternative to changing the Deployment Descriptor, one can edit the WSDL to coerce the client into sending data type information using the xsi:type attribute. The change for the Stock Quote sample is simple: just change the type specified for arg0 from xsd:string to xsd:anyType.

   <wsdl:message name="getQuoteRequest">
      <wsdl:part name="arg0" type="xsd:anyType"/>
   </wsdl:message>
Return to top.

Trace the Stock Quote client again

The TcpTunnelGui utility, included in Apache SOAP, is invaluable is seeing what characters are being sent and received by the client.

  1. Start TcpTunnelGui by running java org.apache.soap.util.net.TcpTunnelGui 81 localhost 8080
  2. In the WSDL file, change localhost:8080 to localhost:81 the one place it occurs.
  3. Run the Stock Quote client again.

The client now sends the following (formatting changed for readability):

POST /soap/servlet/rpcrouter HTTP/1.1
Content-Type: text/xml; charset="UTF-8"
Host: localhost
SOAPAction: ""
Content-Length: 491

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAPSDK1:getQuote xmlns:SOAPSDK1="urn:xmltoday-delayed-quotes">
<arg0 xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:SOAPSDK3="http://www.w3.org/2001/XMLSchema"
      SOAPSDK2:type="SOAPSDK3:string">
IBM
</arg0>
</SOAPSDK1:getQuote>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The arg0 parameter now has type information. The response from the server is the same as it was for the original WSDL.

Return to top.

Resources

SOAP Interoperability with Microsoft and Apache Toolkits - A step by step guide, which shows an Apache client to a VB service.
Accessing a .NET Web Service using Apache/SOAP and Java, although I hope there is an easier way!

Return to top.

Copyright © 2002 Scott Nichol.
16-Sep-2002