It's a perfectly reasonable goal for a Web service toolkit and runtime engine: allow a developer to take a server interface, brand it a Web service, and automatically generate some client-side proxy code from it, all without ever having to eyeball an XML document.
That would be fine if all Web service platforms generated SOAP messages the same way. But, as Web service developers are finding out these days, they don't. And the formats some use by default to produce the XML in SOAP messages are losing ground as the preferred formats in the field. Worse, if two different Web service platforms provide differing levels of support for a certain formatting scheme, watch out when you need to run a client on one and a service on another.
The first part of this article explains the two central decisions developers make when forming SOAP messages—style and use—and how they relate to:
- The communication patterns that Web services support
- Existing Java specifications
- The high-level mechanisms for translating between Java methods and SOAP messages
- The fundamental Web service design choices
The second part shows how to control style and use—starting from both server-side Java and an XML Web service definition—using two Web service platforms:
- Apache Axis 1.1, an open source Web service toolkit and runtime engine.
- Systinet WASP Server 4.5.1 for Java, a commercial Web service toolkit and runtime engine. (Version 4.6 was recently released.)
Part 1: Untangling the terminology
Nowadays, Web service developers are being bombarded with catchphrases: "document/literal," "RPC-style," "message-style," and so on. And judging from mailing list threads and even seminar presentations, not only are many developers just confused about the terms' precise meanings, they are also confusing the terms with each other.
Actually, such misunderstanding is perfectly understandable, considering the imperfect evolution of Web service practices, as you'll see.
SOAP and WSDL XML
First, let's establish some basic, baseline knowledge of the XML in both a SOAP message and a WSDL (Web Services Description Language) document, which defines a Web service. (Speaking of imperfect evolution, the acronym "SOAP" has sloughed off its original meaning, Simple Object Access Protocol.)
A typical SOAP message viewed down to the second level follows:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" > <soap:Header> <!-- header element(s) here --> </soap:Header> <soap:Body> <!-- body element(s) here --> </soap:Body> </soap:Envelope>
<soap:Header> element is not required for the core SOAP functionality discussed in this article and can be omitted. Essentially, the canvas we're trying to paint is the contents—the children, grandchildren, and so on—of the
Here is an abridged version of a typical WSDL document viewed, for the most part, down to the second level:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl" targetNamespace="your namespace here" xmlns:tns="your namespace here" xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap"> <wsdl:types> <xs:schema targetNamespace="your namespace here (could be another) " xmlns:xsd="http://www.w3.org/2001/XMLSchema" <!-- Define types and possibly elements here --> </schema> </wsdl:types> <wsdl:message name="some operation input"> <!-- part(s) here --> </wsdl:message> <wsdl:message name="some operation output"> <!-- part(s) here --> </wsdl:message> <wsdl:portType name="your type name"> <!-- define operations here in terms of their messages --> </wsdl:portType> <wsdl:binding name="your binding name" type="tns:port type name above"> <!-- define style and transport in general and use per operation --> </wsdl:binding> <wsdl:service> <!-- define a port using the above binding and a URL --> </wsdl:service> </wsdl:definitions>
The standard namespaces in a WSDL document are as follows:
- http://schemas.xmlsoap.org/wsdl: Abbreviated
wsdlor made the default namespace
- http://schemas.xmlsoap.org/wsdl/soap: Abbreviated
soap. The elements in this namespace provide the SOAP binding, specifying that the WSDL refers to SOAP messages and not messages of some other type. The
soapbindnamespace is used for elements within the
- http://www.w3.org/2001/XMLSchema: Abbreviated
xsd, for XML Schema definitions, which use the XML-based definition language laid out in the W3C XML Schema specification. Used within the
A quick explanation of the six featured elements follows:
:The root node.
:Contains one or more
<xsd:schema>elements. Within each
<schema>element are simple and complex XML datatype definitions using XML Schema, and, optionally, XML element declarations.
:Defines an XML message placed inside a SOAP message's body. For every request-response operation, you have one uniquely named request message and one uniquely named response message (plus possibly fault messages indicating errors), so don't be surprised if you have to scroll through a thicket of
<message>elements for a Web service with numerous operations. Each message is defined in terms of the types under
:Defines an abstract Web service interface in terms of its operations, where each operation is defined in terms of the above messages.
:Defines a concrete Web service implementation (except for the URL) in terms of the above port type, the use of SOAP, as well as the two XML formatting decisions: style for the entire service (or less commonly, per operation), use per operation.
:Defines a port, or Web service destination, in terms of the above binding plus a URL. The
<service>element is intended to locate a Web service, but obviously you have to know where the Web service is to get to the WSDL in the first place. Alternative location mechanisms, like UDDI (Universal Description, Discovery, and Integration), go beyond the scope of this article.
Gnarly though it may appear, the WSDL format has a certain elegant logic. Note how each lower element type depends on and builds upon the one just above it: A service's port commits a binding to a URL. A binding commits a port type to certain XML formatting rules. A port type's operations are made up of messages. Messages are made up of types, or elements.
The figure below shows the relationships between the salient elements of a WSDL document.
The described WSDL involves a Web service
portType with a single operation,
GetSomething, which uses two messages,
GetSomethingResponse. The figure is color-coded according to namespace. Upward-pointing arrows indicate dependencies where a bold-faced name is derived.
Armed with this knowledge, we can now address some of the touchy issues involved in SOAP message formation.
Patterns, styles, and uses
With Web services, you can think of three communication patterns:
- RPC (remote procedure call): Client sends a server a SOAP request and waits for a SOAP response.
- One-way messaging: Client sends a SOAP request and expects no SOAP response back.
- Asynchronous callback: Client calls service; later, the two parties switch roles for a callback call. This pattern can be built from either of the first two.
Asynchronous callbacks are a topic worthy of their own discussion, but for now, just understand that the pattern exists. As for RPC and one-way messaging, the difference between the two is really quite trivial: one produces a SOAP response and the other doesn't.
In the WSDL, that difference amounts to whether the
<wsdl:operation> element contains a
<wsdl:output> element in addition to
<wsdl:input>. The operation should be defined in both
Now we turn to the two decisions for formatting the contents of a message's
The style, or binding style, decision controls how the elements just under the SOAP body are constructed. The two choices are:
- RPC: Add extra elements to simulate a method call. (Note that RPC is also a communication pattern.)
- Document: Just send the XML as is. There's also a variation called wrapped that is still specified as document.
Here's an example of an RPC-style message:
<tns:matchNoteAndNote xmlns:tns="urn:outline.demo"> <in0 xsi:type="xsd:string">0000000000</in0> <in1 xsi:type="xsd:string">000000000B</in1> </tns:matchNoteAndNote>
RPC relies on some rules. Observe that the root element is qualified with a namespace, but the two child elements use unqualified names. The root element is named after the operation:
opName for a SOAP request,
opNameResponse for a SOAP response. Each child is a parameter, or a return value named
Now here's an example of a document-style message:
<out:getNoteResponse xmlns:out="urn:outline.demo"> <out:note key="000000000B" > <out:content>test</out:content> </out:note> </out:getNoteResponse>
Observe that all elements are defined within the same namespace. With a document-style Web service, you're free to define the XML however you wish because all the XML is explicitly specified.
Next, we examine how binding style is specified in the WSDL. There actually is a
style attribute in the
<soapbind:binding> element, which is the
<wsdl:binding> element's first child. Also, each nonempty
<wsdl:message> has one or more
<wsdl:part> child elements, into which style factors.
Table 1 illustrates the differences between RPC and document:
Table 1. How binding style is specified in a WSDL document
The essence of the distinction lies in the above use of a type attribute versus an element attribute. With document style, you're placing into the SOAP body an XML element that is fully specified under the
<wsdl:types> element. With RPC style, you're just specifying the type so the SOAP engine, using RPC rules, can make it a parameter, or a return value, and then place that parameter and any siblings inside an operation.
The second decision, use, or encoding, concerns how types are represented in XML. The two choices are:
- Literal: Literally follow an XML Schema definition
- SOAP encoded: Follow special encoding rules detailed in the SOAP 1.1 specification (Section 5, to be precise) to produce XML that can contain references pointing within the message
Here's an example of a SOAP-encoded message (with an RPC style):