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 ToolkitGenerate WSDL for the stock quote service and place a copy in the soap web application by running the following commands:
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.
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).
<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>
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.
The TcpTunnelGui utility, included in Apache SOAP, is invaluable is seeing what characters are being sent and received by the client.
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.
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.
The TcpTunnelGui utility, included in Apache SOAP, is invaluable is seeing what characters are being sent and received by the client.
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.