Simple SOAP Payloads

[Previous] [Next]

As you can see, SOAP uses HTTP as the request/response messaging transport. We can add a SOAP request payload in the request message and a response payload in the response message. In this way, we can issue an RPC to any component using HTTP.

The Payload for a Request Message

The SOAP specification defines several SOAP elements that can be used with a SOAP request: envelope, head, and body. The envelope is a container for the head and body. The head contains information about the SOAP message, and the body contains the actual message. Namespaces are used to distinguish the SOAP elements from the other elements of the payload. For example, SOAP-ENV:Envelope, SOAP-ENV:Head, and SOAP-ENV:Body are used in a SOAP document.

The SOAP schema for the envelope will look as follows:

 <?xml version="1.0" ?> <!-- XML Schema for SOAP v 1.1 Envelope --> <!-- Copyright 2000 DevelopMentor, International Business Machines Corporation, Lotus Development Corporation, Microsoft, UserLand Software --> <schema xmlns="http://www.w3.org/1999/XMLSchema" xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/" targetNamespace="http://schemas.xmlsoap.org/soap/envelope/"> <!-- SOAP envelope, header, and body --> <element name="Envelope" type="tns:Envelope"/> <complexType name="Envelope"> <element ref="tns:Header" minOccurs="0"/> <element ref="tns:Body" minOccurs="1"/> <any minOccurs="0" maxOccurs="*"/> <anyAttribute/> </complexType> <element name="Header" type="tns:Header"/> <complexType name="Header"> <any minOccurs="0" maxOccurs="*"/> <anyAttribute/> </complexType> <element name="Body" type="tns:Body"/> <complexType name="Body"> <any minOccurs="0" maxOccurs="*"/> <anyAttribute/> </complexType> <!-- Global Attributes. The following attributes are intended to be usable via qualified attribute names on any complex type referencing them. --> <attribute name="mustUnderstand" default="0"> <simpleType base="boolean"> <pattern value="0|1"/> </simpleType> </attribute> <attribute name="actor" type="uri-reference"/> <!-- 'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification. --> <simpleType name="encodingStyle" base="uri-reference" derivedBy="list"/> <attributeGroup name="encodingStyle"> <attribute name="encodingStyle" type="tns:encodingStyle"/> </attributeGroup> <!-- SOAP fault reporting structure --> <complexType name="Fault" final="extension"> <element name="faultcode" type="qname"/> <element name="faultstring" type="string"/> <element name="faultactor" type="uri-reference" minOccurs="0"/> <element name="detail" type="tns:detail" minOccurs="0"/> </complexType> <complexType name="detail"> <any minOccurs="0" maxOccurs="*"/> <anyAttribute/> </complexType> </schema> 

A SOAP request including the payload defined in the schema would look like this:

 POST /Order HTTP/1.1 Host: www.northwindtraders.com Content-Type: text/xml Content-Length: nnnn SOAPAction: "urn:northwindtraders.com:PO#UpdatePO" <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" xsi:schemaLocation= "http://www.northwindtraders.com/schemas/NPOSchema.xsd"> <SOAP-ENV:Body xsi:type="NorthwindBody"> <UpdatePO> <orderID>0</orderID> <customerNumber>999</customerNumber> <item>89</item> <quantity>3000</quantity> <return>0</return> </UpdatePO> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

NOTE
Notice that the default Body declaration is overridden by using an xsi:type attribute associating NorthwindBody with the Body element. A schema that defines NorthwindBody and the additional elements, such as UpdatePO, will be shown in the section "A Schema for the Body Content of the SOAP Message" later in this chapter.

Because the Body element contains the any element in the SOAP schema, you could also have written SOAP body as follows:

 <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope"> <SOAP-ENV:Body xsi:type="NorthwindBody"> <m:UpdatePO xmlns:m= "http://www.northwindtraders.com/schemas/NPOSchema.xsd"> <orderID>0</orderID> <customerNumber>999</customerNumber> <item>89</item> <quantity>3000</quantity> <return>0</return> </m:UpdatePO> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

As you can see, the payload of a SOAP request is an XML document that contains the parameter values of the method. The HTTP header of this package has identified the UpdatePO method of the Order object as the recipient of this method call. The top-level element of the method call must have the same name as the method identified in SOAPAction.

The elements contained within the top element are the parameters for the method. The preceding example contains four parameters: orderID, customerNumber, item, and quantity. In Microsoft Visual Basic, this method could be written as follows:

 Public Sub UpdatePO(byval orderID as Integer, _ byval customerNumber as Integer, _ byval item as Integer, _ byval quantity as Integer, _ byref return as Integer) 

In Java, this method would look like this:

 public class UpdatePO {public int orderID; public int customerNumber; public int item; public int quantity; public int return;} 

When you are building the request, you will include one element for each in or in/out parameter. This technique of associating one element with each parameter is also known as the element-normal form (ENF). The name of each element is the name of the parameter the element is associated with.

The request can also contain a header element that includes additional information. There are no predefined elements in the header element—you can include any element you want, as long as it is either prefixed by a namespace or the header type is overridden using xsi:type and a type defined in a schema.

We can add a header element to our payload example as shown here:

 <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" xsi:schemaLocation= "http://www.northwindtraders.com/schemas/NPOSchema.xsd"> <SOAP-ENV:Header xsi:type="NorthwindHeader"> <GUID> 10000000-0000-abcd-0000-000000000001 </GUID> </SOAP-ENV:Header> <SOAP-ENV:Body xsi:type="NorthwindBody"> <UpdatePO> <orderID>0</orderID> <customerNumber>999</customerNumber> <item>89</item> <quantity>3000</quantity> <return>0</return> </UpdatePO> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

Because the any element is used in the header element in the SOAP schema, we could also rewrite the SOAP header as follows:

 <SOAP-ENV:Header> <COM:GUID xmlns:COM="http://comobject.Northwindtraders.com"> 10000000-0000-abcd-0000-000000000001 </COM:GUID> </SOAP-ENV:Header> 

In this case, we have created an element named GUID. It will be up to the receiving application to interpret this header, but it's likely that it will be used to instantiate the correct COM object. These additional elements can be considered processing instructions.

You can include a predefined attribute named mustUnderstand as an attribute of a header element. The mustUnderstand attribute can be used to indicate whether the header information is essential for processing of the information. If the header information is essential, mustUnderstand should be set to true. If the receiving element cannot recognize the processing instruction and mustUnderstand is set to 1, the message must be rejected. Thus, we could have the following header element:

 <SOAP-ENV:Header xsi:type="Transaction"> <transactionID mustUnderstand="1"> 10000000 </transactionID > </SOAP-ENV:Header> 

In this case, we are creating an element named TransactionID. This element must be understood by the receiving application, or the message will be rejected.

Sending Messages Using M-POST

You can restrict messages coming through a firewall or a proxy server by using the MPOST method instead of POST. M-POST is a new HTTP method defined using the HTTP Extension Framework located at http://www.w3.org/Protocols/HTTP/ietf-ext-wg. This method is used when you are including mandatory information in the HTTP header, just as you used the mustUnderstand attribute in the SOAP header element.

As we mentioned, SOAP supports both POST and M-POST requests. A client first makes a SOAP request using M-POST. If the request fails and either a 501 status code (Not Implemented status message) or a 510 status code (Not Extended status message) returns, the client should retry the request using the POST method. If the client fails the request again and a 405 status code (Method Not Allowed status message) returns, the client should fail the request. If the returning status code is 200, the message has been received successfully. Firewalls can force a client to use the M-POST method to submit SOAP requests by blocking regular POSTs of the text/xml-SOAP content type.

If you use M-POST, you must use a mandatory extension declaration that refers to a namespace in the Envelope element declaration. The namespace prefix must precede the mandatory headers. The following example illustrates how to use M-POST and the mandatory headers:

 M-POST /Order HTTP/1.1 Host: www.northwindtraders.com Content-Type: text/xml Content-Length: nnnn Man: "http://schemas.xmlsoap.org/soap/envelope; ns=49" 49-SOAPAction: "urn:northwindtraders.com:PO#UpdatePO" 

The Man header maps the URI http://schemas.xmlsoap.org/soap/envelope to the header prefix 49. Any header that has a prefix of 49 will be associated with this URI and will therefore be a mandatory header. In this case, the SOAPAction will be associated with the URI and is a mandatory header.

NOTE
If you use M-POST and do not have any mandatory header elements, an error will occur, resulting in either a 501 or 510 status code.

The Payload for a SOAP Response

Just as our sample SOAP request message contained child elements for all the in and in/out parameters of the method, the SOAP response will contain child elements for each out and in/out parameter. Let's say you have the following Visual Basic function:

 Public Function UpdatePO(byref OrderID as Integer, _ byval CustomerNumber as Integer, _ byval Item as Integer, _ byval Quantity as Integer) as Integer 

In this case, the server would set the orderID variable to some value and return the value to the client. Because the orderID parameter is byref, it is an in/out parameter. UpdatePO is now a function, and it will return a value (a Boolean value, in this case). The return value of the function can be considered an out only parameter.

For this UpdatePO function, the request payload containing all the in and in/out parameters might look like this:

 <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" xsi:schemaLocation= "http://www.northwindtraders.com/schemas/NPOSchema.xsd"> <SOAP-ENV:Body xsi:type="NorthwindBody"> <UpdatePO> <orderID>0</orderID> <customerNumber>999</customerNumber> <item>89</item> <quantity>3000</quantity> </UpdatePO> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

The response package including the payload that contains all the out and in/out parameters would look like this:

 HTTP/1.1 200 OK Content-Type: text/xml Content-Length: nnnn <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" xsi:schemaLocation= "http://www.northwindtraders.com/schemas/NPOSchema.xsd"> <SOAP-ENV:Body xsi:type="NorthwindBody"> <UpdatePO> <orderID>09877</orderID> <return>0</return> </UpdatePO> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

Notice that the SOAP response message doesn't have the SOAPAction header field. This header field is required only in the SOAP request message. During request processing, a SOAP package will be passed to a SOAP application on the server that handles SOAP requests. This SOAP application will in turn pass on the request to the appropriate method.

Sometimes a request cannot be processed properly and errors might occur. Errors can be handled in several ways, depending on where the error occurs. If an error occurs during the transport of the package to the method, the error is usually handled by returning status codes other than 200. An example of this situation is when there is a problem getting the package through a firewall or the specified host does not exist or is down.

Once the information has been passed to the method, it is possible that the application handling the request will experience an error. In this case, you can return a custom HTTP code, use one of the predefined HTTP codes, use an element, such as the return element in the preceding example, or return a SOAP package that contains a Fault element to pass back the error information. Let's look at how to use the Fault element to report errors.

The Fault Element

A Fault element can contain four child elements: faultcode, faultstring, faultactor, and detail. The fault codes are identified at the URL http://schemas.xmlsoap.org/soap/envelope. The currently available code values are shown in the following table.

Currently Available Fault Code Values

Name Meaning
VersionMismatch

The call used an invalid namespace.

MustUnderstand

The receiver did not understand an XML element that was received containing an element tagged with mustUnderstand="true".

Client

These are a class of errors that were caused by improper information in the actual SOAP message. For example, a new order could be missing a required value such as the item number or amount. These errors represent a problem with the actual message content and indicate that the message should not be resent without change. A class of client errors can be created using the dot (.) operator. For example, you could have Client.InvalidPartNumber, Client.InvalidQuantity,and so on.

Server

These errors are related to problems with the server and usually do not represent problems with the actual SOAP message. These messages might be resent at a later time to the server. A class of server errors can be created using the dot (.) operator.

The faultstring element is a string. It is not used by applications; it is used only as a message to users. This element is required. The faultactor element can provide information about which element in the message path caused the fault to occur. The faultactor will be a URI that identifies the source. If the fault occurs in an application that is not the ultimate destination of the message, the faultactor element must be included. If the fault occurs in the ultimate destination, the faultactor is not required but may be included. The detail element is required if the contents of the SOAP Body element couldn't be processed. It provides application-specific error information related to the Body element. You cannot include error information related to the header in the detail element. Any child elements of the detail element must be associated with a namespace.

A return package with a Fault element will look like this:

 HTTP/1.1 200 OK Content-Type: text/xml Content-Length: nnnn <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" xsi:schemaLocation= "http://www.northwindtraders.com/schemas/NPOSchema.xsd"> <SOAP-ENV:Fault> <SOAP-ENV:faultcode>200</SOAP-ENV:faultcode> <SOAP-ENV:faultstring>Must Understand Error </SOAP-ENV:faultstring> <SOAP-ENV:detail xsi:type="Fault"> <errorMessage> Object not installed on server. </errorMessage> </SOAP-ENV:detail> </SOAP-ENV:Fault > </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

Using the faultstring element, you can pass information back to the client that describes the exact error. The faultstring element can handle a wide range of errors.

A Schema for the Body Content of the SOAP Message

As you can see, we have not yet defined the NPO schema located at http://www.northwindtraders.com/schemas/NPOSchema.xsd. This schema can be defined as follows:

 <xsd:schema xmlns:xsd="http://www.w3.org/1999/XMLSchema" targetNamespace="http://schemas.xmlsoap.org/soap/envelope" xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope"> <xsd:complexType name="NorthwindHeader"> <xsd:element name="GUID" type="string"/> </xsd:complexType> <xsd:complexType name="NorthwindBody"> <xsd:element name="UpdatePO"> <xsd:complexType> <element name="orderID" type="integer"/> <element name="customerNumber" type="integer"/> <element name="item" type="double"/> <element name="quantity" type="double"/> </xsd:complexType> </xsd:element> </xsd:complexType> </xsd:schema> 

This schema creates two elements: NorthwindBody and NorthwindHeader. Using the xsi:type attribute, we can extend the SOAP body element with the NorthwindBody complex type and extend the Header element with NorthwindHeader complex type. You can then create the following SOAP document:

 <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope" xsi:schemaLocation= "http://www.northwindtraders.com/schemas/NPOSchema.xsd"> <SOAP-ENV:Header xsi:type="NorthwindHeader"> <COM:GUID xmlns:COM="http://comobject.northwindtraders.com"> 10000000-0000-abcd-0000-000000000001 </COM:GUID> </SOAP-ENV:Header> <SOAP-ENV:Body xsi:type="NorthwindBody"> <UpdatePO> <orderID>0</orderID> <customerNumber>999</customerNumber> <item>89</item> <quantity>3000</quantity> </UpdatePO> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 



Developing XML Solutions
Developing XML Solutions (DV-MPS General)
ISBN: 0735607966
EAN: 2147483647
Year: 2000
Pages: 115
Authors: Jake Sturm

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net