Sun Java Solaris Communities My SDN Account Join SDN
 
Article

The Java Web Services Developer Pack, Part 2

 
 

What's This About? | JAX-RPC | JAXM | Build and Run the Sample Application

Web Services Developer Pack

XML Technologies for RPC Calls and Messaging

One of the things that makes the Web services model so attractive is that it's built on standard technologies, especially XML technologies, that have wide industry acceptance. The first article in the series introduced one of these XML technologies, SOAP, a major underpinning of the communication mechanism for Web services. It showed how the SOAP protocol is used in the exchange of messages in a distributed environment. It also described the structure of a SOAP message. Both JAX-RPC and JAXM work in conformance with the SOAP 1.1 specification and the SOAP 1.1 with Attachments specification. The RPC calls made through JAX-RPC conform to these specifications, and so too do the messages exchanged through JAXM. This section highlights some of the important features of SOAP that were introduced in the first article in the series, and shows how you can use SOAP for RPC calls as well as for messaging. The section also covers another XML-based technology, Web Services Description Language (WSDL), that plays an important role in RPC calls.

A SOAP Refresher

SOAP is an XML-based protocol for exchanging information in a distributed environment.

Here are some of the important characteristics of SOAP that were presented in the first article in the series:

  • SOAP (which is defined by the SOAP 1.1 specification) is an XML-based protocol for exchanging information in a distributed environment.
  • SOAP is a generally accepted standard for Web services.
  • The basic item of transmission in SOAP is the SOAP message.
  • A SOAP message consists of a mandatory SOAP envelope, an optional SOAP header, and a mandatory SOAP body.

What those items mean is that if a Web services client exchanges some information with a Web service, what gets exchanged is a SOAP message that conceptually looks like this:

A SOAP Message (Conceptually)
Click image to enlarge

A SOAP message is an XML document. The envelope is the top element of the XML document, and is represented by an Envelope element. The envelope can contain namespace declarations as well as additional attributes such an encoding style. An XML namespace defines a collection of names that can be used in XML elements and attributes. The namespace identifies the scope for a name, so that "name clashes" can be avoided. In particular, namespace declarations are designed to distinguish the names used in the XML document from the names used in an application that might process the XML document. They also distinguish names within the XML document, so that two elements with the same name, but associated with different namespaces, can be correctly understood as being different. An encoding style identifies the data types recognized by SOAP messages, and specifies rules for how these data types are serialized, that is, transformed for transport across the Web.

The header is represented by a Header element. As mentioned before, the header is optional. However, if it's included in a SOAP message, it must be the first child of the Envelope element. The header, through attributes, extends the SOAP message. In other words, it adds information beyond what is in the body of the SOAP message. It's important to understand that as a SOAP message travels from an originator (a client application) to a final destination (for example, an application providing a requested service), it potentially passes through a set of intermediate nodes along the path. Each node is an application that can receive and forward SOAP messages. The SOAP header can be used to indicate some additional processing at a node, that is, processing independent of the processing done at the final destination. For example, the header could be used to request that each message be logged at a particular node.

The body, represented by a Body element, contains the "payload", that is, the information intended for the final destination. The Body element can optionally contain a Fault element that is used to hold error and status information returned by a processing node. The Body element must be an immediate child element of a SOAP Envelope element. If the envelope contains a header, the Body element must immediately follow the Header element.


Here's an example of a SOAP message:

<SOAP-ENV: Envelope
  xmlns:SOAP-ENV=
    "http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV: 
    encodingStyle=
      "http://schemas.xmlsoap.org/soap/encoding/">
        <SOAP-ENV:Header>
           <t:Transaction xmlns:t="some-URI">
              SOAP-ENV:mustUnderstand="1"> 
                  5
           </t:Transaction>
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
           <m:GetLastTradePrice xmlns:m="some-URI">
              <symbol>DEF</Symbol>
           </m: GetLastTradePrice>
        </SOAP-ENV:Body>
</SOAP-Envelope>

The Envelope element specifies:

  • A namespace. The URI http://schemas.xmlsoap.org/soap/envelope/ identifies the namespace used for this SOAP message. This is the standard namespace for all SOAP messages. Notice the prefix SOAP-ENV. This prefix maps to the namespace, so that any additional references to the prefix in the SOAP message, are references to that namespace.
     
  • An encoding style. The URI http://schemas.xmlsoap.org/soap/encoding/ identifies the encoding style for "Section 5" encodings, that is, the SOAP encoding described in Section 5 of the SOAP specification. Section 5 define rules for encoding data types in XML, and rules for serialization.

The Header element specifies:

  • A Transaction element. The URI represented by "some-URI" identifies the namespace for the element.
     
  • A demand to process the header. The attribute value mustUnderstand=1 means that the receiver of the header must process it. SOAP provides an attribute, called the "SOAP actor", whose value is a URI. The URI identifies the node that receives the SOAP header (remember that a SOAP message can potentially travel through multiple nodes before arriving at a final destination). Because the SOAP actor attribute is not specified in this example, it means that header should be received at the final destination. And because mustUnderstand=1 is specified, that node must process the header.
     
  • A value of 5. Presumably, the receiver knows how to process this value.

The Body element specifies a GetLastTradePrice element (and its namespace), and a subordinate element DEF.

SOAP can be used for RPC calls as well as for messaging.

If you've guessed that this example has something to do with stock quotes, you're right. The SOAP message is designed to retrieve the current price of a stock. Specifically, the SOAP message includes a request for the current stock price (GetLastTradePrice), and passes a symbol (DEF) that identifies the stock. This looks similar to a Remote Procedure Call, where GetLastTradePrice represents a method, and DEF represents a parameter to the RPC call. In fact, that's what's happening here. SOAP is being used to transmit an RPC call. Using SOAP for RPC is one of two approaches to using SOAP. The other is using SOAP for messaging.

SOAP for RPC

The SOAP specification states:

One of the design goals of SOAP is to encapsulate and exchange RPC calls using the extensibility and flexibility of XML.

To meet that goal, the SOAP specification includes a section that describes how to represent RPC calls and responses. The section identifies the following as information needed in an RPC call:

  • The URI of the target object
  • A method name
  • An optional method signature
  • The parameters to the method
  • Optional header data

All of this information, with the exception of the URI of the target object, is carried in a SOAP message. The URI is provided by the transport protocol, such as HTTP, that is used to communicate the SOAP message. The section then specifies how the other information needed in the call is represented. Here are some of the significant items in the specification:

RPC method calls and responses are carried in the SOAP Body element. In the SOAP message example above, the Body element contains the following:

        <SOAP-ENV:Body>
           <m:GetLastTradePrice xmlns:m="some-URI">
              <symbol>DEF</Symbol>
           </m: GetLastTradePrice>
        </SOAP-ENV:Body>

This represents a method call. Here GetLastTradePrice is the method called, and DEF is the method parameter. This indicates something important about using SOAP for RPC (as opposed to using SOAP for messaging). When using SOAP for RPC, the client knows which procedure it wants to call, and knows what parameters that procedure requires. (By comparison, when using SOAP for messaging, the client doesn't necessarily know what application will process the request.)

The response to the method call is also contained in a SOAP message Body element. Assume, for example, that the Body element of the response looks like this:

        <SOAP-ENV:Body>
           <m:GetLastTradePriceResponse xmlns:m="some-URI">
              <price>42.40</price>
           </m: GetLastTradePriceResponse>
        </SOAP-ENV:Body>

Notice the response element GetLastTradePriceResponse. Although SOAP does not require it, the convention is to give the response element the same name as the method name, with the string "Response" appended to it.

SOAP can be used for one-way (asynchronous) or two-way (synchronous) requests.

Although a response is shown here, SOAP does not require that the receiver of a request return a response. In fact, "one-way requests", where a SOAP client asks for a service without expecting a response, are perfectly valid. Another term used for one-way is "asynchronous". By comparison, a "two-way request" is one where a SOAP client asks for a service and waits for a response before proceeding. Another term for two-way is "synchronous".

RPC method calls and responses are modeled as structures. SOAP specifies that:

  • A method call and its response are both modeled as structures called structs, and that the structs have the same name and type as the method call or response.
  • A struct is a compound value, each of whose member values, called accessors, have a distinct name.
  • The struct for the method call must contain an accessor for each method parameter.
  • The accessors must have the same name and type as the method parameters, and must appear in the struct in the same order as in the method signature.

So in the example above, the method call GetLastTradePrice is represented by a struct with the same name and type as the method. That struct contains one accessor, DEF, that has the same name and type as the parameter to the method.

The same sort of rules apply to the response:

  • The struct for the method response must contain an accessor for each output parameter.
  • Each of these accessors must have the same name and type as its respective output parameter.
  • Each accessor must appear in the struct in the same order as in the method signature.

In the example above, the method response GetLastTradePriceResponse is represented by a struct that contains one accessor, price, that has the same name and type as the output parameter.

RPC method calls and responses can be encoded according to specified encoding rules. Notice again that the Envelope element in the SOAP example identifies an encoding style. Specifically, the URI http://schemas.xmlsoap.org/soap/encoding/ identifies the encoding style for Section 5 encodings. The encoding rules essentially identify the types recognized by SOAP. For example, the Section 5 encoding rules identify simple types such as int and float, and compound types such as structs and arrays. The serialization rules specify how objects are represented in XML so that they can be exchanged between a client and a server. For example, the Section 5 serialization rules state that a simple value is represented as character data, that is, without any subelements, and a compound value is encoded as a sequence of elements.

Together, the Section 5 encoding style and the SOAP for RPC rules provide a framework for using SOAP for RPC. The framework allows an application to use RPC call semantics in an XML based, client-server scenario as follows:

Using SOAP for RPC
Click image to enlarge

  1. An application makes RPC calls following the SOAP for RPC rules.
  2. A SOAP client implementation serializes the calls to XML following Section 5 encodings.
  3. A SOAP server implementation deserializes the calls from XML following Section 5 encodings, for use by a server application.
  4. Then the process is reversed:

  5. The server application returns a response following the SOAP for RPC rules.
  6. The SOAP server implementation serializes the response to XML following Section 5 encodings.
  7. The SOAP client implementation deserializes the response following Section 5 encodings, for use by the client application.


Although Section 5 encoding style appears here to be mandatory, it's actually not. Any encoding style is allowed by SOAP. Of course, to make the information exchange sensible between the client and the server, both need to agree on the encoding style. The advantage of using Section 5 encoding is that it's a standardized encoding style, something that aligns well with the standardized protocols that underlie Web services.

Transport Protocols. One question you might ask at this point is "How does a SOAP message get transported from the client to the server and back?" The answer is that it's bound to a transport protocol such as HTTP or SMTP. SOAP does not require a particular transport binding, although HTTP is typically used to transport SOAP messages and responses. In fact HTTP is the only protocol binding that's covered in the SOAP 1.1 specification. Here, for example, is a SOAP message embedded in an HTTP 1.1 POST request. The POST action transports the SOAP message to an HTTP server.

POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"

<SOAP-ENV: Envelope
  xmlns:SOAP-ENV=
    "http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV: 
    encodingStyle=
      "http://schemas.xmlsoap.org/soap/encoding/">
        <SOAP-ENV:Body>
           <m:GetLastTradePrice xmlns:m="some-URI">
              <symbol>DEF</Symbol>
           </m: GetLastTradePrice>
        </SOAP-ENV:Body>
</SOAP-Envelope>

SOAP for Messaging

Although the focus so far has been on SOAP for RPC, SOAP can also be used for messaging. In messaging, the client sends a document (rather than an RPC call) for the server to process. The document contains information in a format that both the client and server can understand. For example, the document could be something that both the client and server recognize as a purchase order. The server then processes the purchase order, and could return a response (perhaps confirming that the purchase order was received).

It's important to understand that the messaging client does not call a specific method -- in the purchase order example, the messaging client does not call a purchase order method. In fact, the client might not know what program on the server actually processes the request. Instead, the client relies on the server to invoke the appropriate application to process the request because the server understands the format of the message it receives. Similarly, what the server returns is not a method response, but rather a response generated by the processing application.

This example indicates that the server could return a response, but it doesn't have to. As is the case when using SOAP for RPC, SOAP for messaging does not require that the receiver of a request return a response. In fact, one-way (asynchronous) requests are probably more typical in messaging than two-way (synchronous) requests.

The architecture of a SOAP message is the same for messaging as it is for RPC. In both cases, the message contains an envelope, an optional header, and a body. For messaging, the payload in the body is the document passed by the client for processing by the server. Here's an example of a SOAP message used for messaging:

<SOAP-ENV: Envelope
  xmlns:SOAP-ENV=
    "http://schemas.xmlsoap.org/soap/envelope/"
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
           <bp:GetBookDetails xmlns:bp="http://bookprovider.com">
              <searchCriteria>ISBN</searchCriteria>
              <searchValue>0123454321</searchCriteria>
           </m: GetBookDetails>
        </SOAP-ENV:Body>
</SOAP-Envelope>

Notice that the body contains an element GetBookDetails that contains two subelements searchCriteria and searchValue. Assume that GetBookDetails is recognized as a structure that contains information about books, in particular, the International Standard Book Number (ISBN). Assume too that the server processes the message by searching a database of book information, using the ISBN value as search criteria. Finally, assume that the server returns detailed information about the book that has the specified ISBN value.

In other respects, SOAP for messaging is similar to SOAP for RPC. In particular, when used for messaging:

  • A SOAP message can potentially pass through a set of intermediate nodes (applications) along the path from the client to the final destination. Any of these nodes can perform additional processing on the message, such as security checking, as directed by the SOAP header.
  • A SOAP message can identify one or more namespaces that identify the scope of names used in the message. Notice in the messaging example, the Envelope element specifies the standard namespace for SOAP messages (http://schemas.xmlsoap.org/soap/envelope/), and the Body element specifies a namespace (http://bookprovider.com) that defines the scope of names for the body.
  • A SOAP message can identify an encoding style, although an encoding style is more typically specified in SOAP for RPC. There is no default encoding style for a SOAP message.

SOAP Messages With Attachments

The SOAP 1.1 specification does not cover attachments to SOAP messages. For example, if you send a SOAP message that conforms to the SOAP 1.1 specification, you send a payload that either represents an RPC call or that contains a document for messaging. But what if you want to attach something to the SOAP message, say an image? A standard way of doing this is described in the SOAP Messages With Attachments specification. This specification describes how to attach one or more items to a SOAP message, no matter what content these items hold. For example, an attachment can be an image, audio, text, even an XML document.

A SOAP message with attachments, which the specification calls a "SOAP message package", conceptually looks like this.

A SOAP Message With Attachments (Conceptually)
Click image to enlarge

The SOAP Messages With Attachments specification takes a MIME approach in describing how to build a SOAP message package. MIME, which stands for Multipurpose Internet Mail Extensions, is a standard that extends the format of Internet mail to allow for things like multipart message bodies.

A message that conforms to the MIME standard consists of a header and a body. The header contains various fields that contain information about the message. For example, the MIME-Version header field specifies which version of the MIME standard applies to the message. Another header field, named CONTENT-TYPE specifies the type of data in the body of the message. For example, the CONTENT-TYPE field value Text specifies that the body contains text, and a value of Audio specifies audio data. One CONTENT-TYPE field value has particular relevance for SOAP message packages. It's the CONTENT-TYPE field value Multipart/Related. This value specifies that the body contains a compound object consisting of several interrelated body parts. This is the MIME data type that is used to construct a SOAP message package.

A Multipart/Related type of compound object has a root body part (by default, this is the first body part in the compound object) and one or more related body parts. Complicating matters is that fact that each body part has its own header and body. The MIME standard further specifies that each body part in a MIME message is separated from another body part at a boundary, and that a boundary is identified in a parameter of the CONTENT-TYPE field. So putting all this together, a SOAP message package consists of a SOAP message that is contained in the root body part, and one or more attachments that are other body parts separated from each other at a boundary.


Here's an example of a SOAP message package. The SOAP message is in the root body part. The value of the start parameter in the CONTENT-TYPE field of the header points to content of the SOAP message (claim061400a.xml@claiming-it.com). The package contains an attachment that's an image (claim061400a.tiff@claiming-it.com).

MIME-Version: 1.0
Content-Type: Multipart/Related; 
 boundary=MIME_boundary; type=text/xml; 
 start="<claim061400a.xml@claiming-it.com>"
Content-Description: 
 This is the optional message description.

--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <claim061400a.xml@claiming-it.com>

<?xml version='1.0' ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
..
<theSignedForm href="cid:claim061400a.tiff@claiming-it.com"/>
..
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

--MIME_boundary
Content-Type: image/tiff
Content-Transfer-Encoding: binary
Content-ID: <claim061400a.tiff@claiming-it.com>

...binary TIFF image...
--MIME_boundary--

Notice that the SOAP message refers to the attached image. SOAP 1.1 allows for an accessor to point to a URI. The URI can provide any type of resource, including a non-XML resource such as an image.

WSDL

WSDL is an XML-based language for describing a Web service.

How does a Web services client know what format to use in making a request to a server? For that matter, how do the client and the server know what the request means? In SOAP for messaging, the answer is that there's a previous agreement about the format and meaning of SOAP messages exchanged between the client and the server. The client and server know what a document representing a purchase order looks like because there's previous agreement about its format. But what about SOAP for RPC? How does a Web services client know what method to call, what arguments to pass, and what to expect in response? In fact, how does the client know to expect a response? The answers to all these questions are provided by information in an XML document, called the WSDL document, that contains a description of the Web service's interface and semantics.

A WSDL document contains information specified in Web Service Description Language (WSDL), as defined in the WSDL specification. WSDL defines an XML schema for describing a Web service. To uncover the description for a Web service, a Web services client needs to find the service's WSDL document. One way, perhaps the most typical way, to do this is for the client to find a pointer to the WSDL document in the Web service's UDDI registration. (However the UDDI specification doesn't mandate such a link.) A typical scenario is that a business registers its service in a UDDI registry. The registry entry includes a pointer to a WSDL file that contains the WSDL document for the service. Another business searches the registry and finds the service. A programmer uses the interface and semantic information in the WSDL document to construct the appropriate calls to the service.

Describing the Abstract

WSDL deals in the abstract. A WSDL document describes a Web service as a collection of abstract items called "ports" or "endpoints". A WSDL document also defines the actions performed by a Web service and the data transmitted to these actions in an abstract way. Actions are represented by "operations", and data is represented by "messages". A collection of related operations is known as a "port type". A port type constitutes the collection of actions offered by a Web service. What turns a WSDL description from abstract to concrete is a "binding". A binding specifies the network protocol and message format specifications for a particular port type. A port is defined by associating a network address with a binding. If a requester locates a WSDL document, and finds the binding and network address for each port, it can call the service's operations according to the specified protocol and message format.

WSDL Document

What's in a WSDL document? Here is an example. The example illustrates a WSDL document for a service that provides stock quotes. This is the service that was called in the example illustrated in A SOAP Refresher. Recall that the application that requests this service supplies a symbol for a specific stock. The service responds with the current price of the stock. Notice that the document contains the following elements:

definitions. In WSDL terms, the description of a Web service's interface is its "definition", marked by the definitions element. This is the root element in a WSDL document. A definitions element specifies a name for the definition (in this example, StockQuote) and points (using URIs) to pertinent namespaces. All WSDL files need to point to a WSDL namespace, a SOAP namespace, and an XML Schema Definition (XSD) namespace. A WSDL file can also point to a target namespace for the associated Web service. In this example, a target namespace for the Web service is located at the URI http://example.com/stockquote.wsdl. Here is part of the complete definitions structure for the stock quote service:

<definitions name="StockQuote"
   targetNamespace="http://example.com/stockquote.wsdl"
   xmlns:tns="http://example.com/stockquote.wsdl"
   xmlns:xsd1="http://example.com/stockquote.xsd"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns="http://schemas.xmlsoap.org/wsdl/">

types. This structure, marked by the types element, contains data type definitions using some type system (such as XSD). WSDL uses a small set of primitive data types that are defined in XSD. Using the types structure in a WSDL document, you can define complex types that build on these basic types. These types can then be used in the operations defined for the Web service. Notice that the example defines two complex types, one that contains an element named tickerSymbol that is based on the primitive data type string, and another complex type that contains the element price that is based on the primitive data type float. Here is the types structure for the stock quote service:

<types>
   <schema targetNamespace="http://example.com/stockquote.xsd"
    xmlns="http://www.w3.org/2000/10/XMLSchema">
      <element name="TradePriceRequest">
         <complexType>
            <all>
               <element name="tickerSymbol" 
                    type="string"/>
            </all>
         </complexType>
      </element>
      <element name="TradePrice">
         <complexType>
            <all>
      <element name="price" type="float"/>
            </all>
         </complexType>
      </element>
   </schema>
</types>

message. The message element describes data that is passed to and from the operations defined for the Web service. An operation identifies an action or set of actions offered by the Web service. In essence, a message describes the parameters that are passed to and from an operation. Messages are made up of parts (marked by the part element). This allows for multi-part data to be passed to an operation, for example, a purchase order with an accompanying invoice can be passed to an auditing service. In the StockQuote example, two messages are defined: GetLastTradePriceInput and GetLastTradePriceOutput. Each is a one-part message. Notice that TradePriceRequest is the part defined in GetLastTradePriceInput. Recall that it was defined in the type structure as containing the type tickerSymbol. TradePrice, the part defined in GetLastTradePriceOutput, was defined in the type structure as containing the type price. Here are the messages defined for the stock quote service:

<message name="GetLastTradePriceInput">
   <part name="body" element="xsd1:TradePriceRequest"/>
</message>

<message name="GetLastTradePriceOutput">
   <part name="body" element="xsd1:TradePrice"/>
</message>

port type. The portType structure defines the operations and messages for the Web service. In other words, it identifies the distinct actions provided by the Web service, and the data passed to each one. Each operation in the portType structure is marked with the operation element. The port type structure has a grammar that identifies the message-passing protocol for the operation, for example, one-way or request-response. Notice the one operation defined in the StockQuote example. The port type in the example has a grammar for a request-response protocol. The operation named GetLastTradePrice specifies an input message (GetLastTradePriceInput) and a output (response) message (GetLastTradePriceOutput). Remember that GetLastTradePriceInput has the type tickerSymbol, and TradePrice has the type price. This means that the GetLastTradePrice operation takes a tickerSymbol as input, and returns a price. Here's the port type defined for the stock quote service:

<portType name="StockQuotePortType">
   <operation name="GetLastTradePrice">
       <input message="tns:GetLastTradePriceInput"/>
       <output message="tns:GetLastTradePriceOutput"/>
   </operation>
</portType>

binding. The binding structure defines the message format and protocol details for operations and messages associated with a particular portType. Typically the binding structure identifies SOAP as the protocol for the binding. This is the case in the StockQuote example. Notice that the binding structure in the example specifies additional SOAP-specific information. The soap:operation element specifies a SOAPAction header URI of http://example.com/GetLastTradePrice. The URI indicates the intent of the message (in this case, a SOAP message). This allows it to perform conditional processing based on the presence of the SOAPAction header. The input and output elements in the binding indicates that the input and output messages to and from GetLastTradePrice reference a concrete schema definition using type attribute. Here's the binding defined for the stock quote service:

<binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType">
   <soap:binding style="document" transport=
       "http://schemas.xmlsoap.org/soap/http"/>
   <operation name="GetLastTradePrice">
       <soap:operation soapAction=
         "http://example.com/GetLastTradePrice"/>
       <input>
          <soap:body use="literal"/>
       </input>
       <output>
          <soap:body use="literal"/>
       </output>
   </operation>
</binding>

service. The service structure defines a collection of related ports that comprise a Web service. Each port identifies a binding and an address for the binding. In the StockQuote example, a service named StockQuoteService is defined to have one port StockQuotePort. The binding for the port is StockQuoteBinding and the address for the binding is http://example.com/stockquote. Here's the service structure defined for the stock quote service:

<service name="StockQuoteService">
   <documentation>My first service</documentation>
   <port name="StockQuotePort" binding="tns:StockQuoteBinding">
       <soap:address location="http://example.com/stockquote"/>
   </port>
</service>



[<<BACK] [TOP] [NEXT>>]