Now that you have a basic understanding of SOAP, it's time to zoom in and fill in the blanks. The last section provided an overview of SOAP; this section gives you more technical details that the basic introduction left out.
SOAP uses the namespace for version control. If the SOAP envelope is in the http://schemas.xmlsoap.org/soap/envelope/ namespace, then the request is SOAP 1.1. If the SOAP envelope is in the http://www.w3.org/2001/09/soap-envelope namespace, then the request is draft SOAP 1.2.
The URI for SOAP 1.2 is likely to change between the draft and the release of the actual recommendation. If anything, the URI should drop the month indicator and be of the following form (assuming the recommendation is published in 2002):
Check the W3C Web site for the most recent URI.
If a SOAP 1.2 node receives a SOAP 1.1 request, it can either process it as SOAP 1.1 or reject it with a VersionMismatch fault message. In any case, a VersionMismatch fault message is always returned with the SOAP 1.1 URI so that older clients can decode the response.
SOAP 1.2 defines an optional Upgrade element, in the http://www.w3.org/2001/09/soap-upgrade namespace, that lets the server specify which versions it recognizes. If present, Upgrade must appear in the header, not the body. See Listing 9 for an example.
Listing 9VersionMismatch fault with the Upgrade element.
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Header> <upg:Upgrade xmlns:upg="http://www.w3.org/2001/09/soap-upgrade"> <envelope qname="ns1:Envelope" xmlns:ns1="http://www.w3.org/2001/09/soap-envelope"/> </upg:Upgrade> </env:Header> <env:Body> <env:Fault> <faultcode>env:VersionMismatch</faultcode> <faultstring>Requires SOAP 1.2</faultstring> </env:Fault> </env:Body> </env:Envelope>
Recall from the earlier discussion that the header is the place to put auxiliary information. Typically it provides storage for options on how to process the call.
The header is similar to email headers: It is not the message itself, but it provides information that may be useful (or even essential) in decoding the payload. For example, ebXML uses the header to store routing information in an ebXML-defined MessageHeader. (This is the smallest ebXML message possible. Indeed, ebXML defines many other elements, but their use is optional.)
Listing 10 is an example of an ebXML header. Because ebXML is outside the scope of this article, we encourage you to turn to http://www.ebxml.org if you want specific information on these elements. However, you are sure to recognize routing information (From, To, Service, Action), as well as message identifiers (MessageData). The CPAId element points to the Collaboration Protocol Agreement that details how the partners ("partner" is ebXML jargon for the parties in the transaction) work together.
Listing 10An ebXML Header
<env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:eb="http://www.ebxml.org/namespaces/messageHeader"> <eb:MessageHeader env:mustUnderstand="1" eb:version="1.0"> <eb:From><eb:PartyId>urn:duns:374950798</eb:PartyId></eb:From> <eb:To><eb:PartyId>urn:duns:912345678</eb:PartyId></eb:To> <eb:CPAId>http://www.psol.com/cpas/default.xml</eb:CPAId> <eb:ConversationId>20011115-122303-28572</eb:ConversationId> <eb:Service>urn:services:SupplierOrderProcessing</eb:Service> <eb:Action>NewOrder</eb:Action> <eb:MessageData> <eb:MessageId>email@example.com</eb:MessageId> <eb:Timestamp>2001-11-15T11:12:12Z</eb:Timestamp> </eb:MessageData> </eb:MessageHeader> </env:Header>
SOAP defines two attributes specifically for the header: env:mustUnderstand and env:actor. A client attaches the env:mustUnderstand attribute (with a value of 1 for true) to elements that are essential for processing the call.
A node should not attempt to process a request if it does not recognize one or more elements flagged with env:mustUnderstand. In Listing 10, the MessageHeader is flagged with env:mustUnderstand because servers should not attempt to process ebXML requests unless they support the MessageHeader.
The other attribute is env:actor. It signals that the element is intended for a given node. Remember Figure 3, which shows that the proxy does not pass the header to the ultimate node. The proxy uses the env:actor to decide which header elements, if any, are for its own consumption.
The env:actor attribute contains the URI of the node or the special URI http://schemas.xmlsoap.org/soap/actor/next for SOAP 1.1. For SOAP 1.2 it contains http://www.w3.org/2001/09/soap-envelope/actor/next, which stands for the next node.
In most cases, SOAP lets the application define the content of the body. The one exception is when there's an error for which SOAP defines the env:Fault. The SOAP fault provides minimal common ground between different SOAP implementations in case of a protocol error.
The content of env:Fault is detailed in the following list. Note that the Fault element is prefixed with a namespace but its content is not (in an XML schema the content would be written as local elements):
faultcode is a code that indicates the error. This element is required.
faultstring is an human-readable error message. It is required.
faultactor is the URI of the node that reports the error. It is required only if the node reporting the error is not the ultimate node.
detail contains additional, application-specific information on the error. It is required if the error took place in the body; it is forbidden otherwise.
SOAP defines the following error codes for the faultcode field:
VersionMismatch indicates the node does not recognize the version of SOAP used; see Listing 9 for an example.
MustUnderstand indicates the node does not recognize a block flagged with mustUnderstand.
Client indicates the node cannot process the message because of the client's fault, for example, when the message is not formatted correctly.
Server indicates the error is not due to the message itself but rather the state in which the server was.
DataEncodingUnknown indicates the node does not recognize the encodingStyle. This is defined only in SOAP 1.2.
The codes should be placed in the envelope namespace. It is possible to extend the code to provide a more detailed error message if you use the dot (.) as a separator. For example, a error code for Java exceptions could be defined as Server.Exception. The server would return this error:
<env:Envelope xmlns:env="http://www.w3.org/2001/09/soap-envelope"> <env:Body> <env:Fault> <faultcode>env:Server.Exception</faultcode> <faultstring>Null pointer exception</faultstring> <detail> <stackTrace> java.lang.NullPointerException: at com.psol.jws.TroubleMaker(TroubleMaker.java:148) at java.lang.Thread.run(Thread.java:484) </stackTrace> </detail> </env:Fault> </env:Body> </env:Envelope>