Chapter 12. SOAP
SOAP is the Simple Object Access Protocol. If you haven't heard of it by now, you've probably been living under a rock somewhere. It's become the newest craze in web programming, and is integral to the web services fanaticism that has taken hold of the latest generation of web development. If you've heard of .NET from Microsoft or the peer-to-peer "revolution," then you've heard about technologies that rely on SOAP (even if you don't know it). There's not one but two SOAP implementations going on over at Apache, and Microsoft has hundreds of pages on their MSDN web site devoted to it (http://msdn.microsoft.com).
In this chapter, I explain what SOAP is, and why it is such an important part of where the web development paradigm is moving. That will help you get the fundamentals down, and prepare you for actually working with a SOAP toolkit. From there, I briefly run over the SOAP projects currently available, and then delve into the Apache implementation. This chapter is not meant to be the complete picture on SOAP; the next chapter fills in lots of gaps. Take this as the first part of a miniseries; many of your questions at the end of this chapter will be answered in the next.
12.1. Starting Out
The first thing to do is get an understanding of what SOAP is. You can read through the complete W3C note submission, which is fairly lengthy, at http://www.w3.org/TR/SOAP. When you take away all of the hype, SOAP is just a protocol. It's a simple protocol (to use, not necessarily to write), based on the idea that at some point in a distributed architecture, you'll need to exchange information. Additionally, in a system that is probably overtaxed and process-heavy, this protocol is lightweight, requiring a minimal amount of overhead. Finally, it allows all this to occur over HTTP, which allows you to get around tricky issues like firewalls and keep away from having all sorts of sockets listening on oddly numbered ports. Once you get that down, everything else is just details.
Of course, I'm sure you're here for the details, so I won't leave them out. There are three basic components to the SOAP specification: the SOAP envelope, a set of encoding rules, and a means of interaction between request and response. Begin to think about a SOAP message as an actual letter; you know, those antiquated things in envelopes with postage and an address scrawled across the front? That analogy helps SOAP concepts like "envelope" make a lot more sense. Figure 12-1 seeks to illustrate the SOAP process in terms of this analog.
Figure 12-1. The SOAP message process
With this picture in your head, let's look at the three components of the SOAP specification. I cover each briefly and provide examples that illustrate these concepts more completely. Additionally, it's these three key components that make SOAP so important and valuable. Error handling, support for a variety of encodings, serialization of custom parameters, and the fact that SOAP runs over HTTP make it more attractive in many cases than the other choices for a distributed protocol. Additionally, SOAP provides a high degree of interoperability with other applications, which I delve into more completely in the next chapter. For now, I want to focus on the basic pieces of SOAP.
12.1.1. The Envelope
The SOAP envelope is analogous to the envelope of an actual letter. It supplies information about the message that is being encoded in a SOAP payload, including data relating to the recipient and sender, as well as details about the message itself. For example, the header of the SOAP envelope can specify exactly how a message must be processed. Before an application goes forward with processing a message, the application can determine information about a message, including whether it will even be able to process the message. Distinct from the situation with standard XML-RPC calls (remember that? XML-RPC messages, encoding, and the rest are all wrapped into a single XML fragment), with SOAP actual interpretation occurs in order to determine something about the message. A typical SOAP message can also include the encoding style, which assists the recipient in interpreting the message. Example 12-1 shows the SOAP envelope, complete with the specified encoding.
Example 12-1. The SOAP envelope
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://myHost.com/encodings/secureEncoding" > <soap:Body> <article xmlns="http://www.ibm.com/developer"> <name>Soapbox</name> <url> http://www-106.ibm.com/developerworks/library/x-soapbx1.html </url> </article> </soap:Body> </soap:Envelope>
You can see that an encoding is specified within the envelope, allowing an application to determine (using the value of the encodingStyle attribute) whether it can read the incoming message situated within the Body element. Be sure to get the SOAP envelope namespace correct, or SOAP servers that receive your message will trigger version mismatch errors, and you won't be able to interoperate with them.
The second major element that SOAP brings to the table is a simple means of encoding user-defined datatypes. In RPC (and XML-RPC), encoding can only occur for a predefined set of datatypes: those that are supported by whatever XML-RPC toolkit you download. Encoding other types requires modifying the actual RPC server and clients themselves. With SOAP, however, XML schemas can be used to easily specify new datatypes (using the complexType structure discussed way back in Chapter 2, "Nuts and Bolts"), and those new types can be easily represented in XML as part of a SOAP payload. Because of this integration with XML Schema, you can encode any datatype in a SOAP message that you can logically describe in an XML schema.
The best way to understand how SOAP invocation works is to compare it with something you already know, such as XML-RPC. If you recall, an XML-RPC call would look something like the code fragment shown in Example 12-2.
Example 12-2. Invocation in XML-RPC
// Specify the XML parser to use XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser"); // Specify the server to connect to XmlRpcClient client = new XmlRpcClient("http://rpc.middleearth.com"); // Create the parameters Vector params = new Vector( ); params.addElement(flightNumber); params.addElement(numSeats); params.addElement(creditCardType); params.addElement(creditCardNum); // Request reservation Boolean boughtTickets = (Boolean)client.execute("ticketCounter.buyTickets", params); // Deal with the response
I've coded up a simple ticket counter-style application. Now, look at Example 12-3, which shows the same call in SOAP.
Example 12-3. Invocation in SOAP
// Create the parameters Vector params = new Vector( ); params.addElement( new Parameter("flightNumber", Integer.class, flightNumber, null)); params.addElement( new Parameter("numSeats", Integer.class, numSeats, null)); params.addElement( new Parameter("creditCardType", String.class, creditCardType, null)); params.addElement( new Parameter("creditCardNumber", Long.class, creditCardNum, null)); // Create the Call object Call call = new Call( ); call.setTargetObjectURI("urn:xmltoday-airline-tickets"); call.setMethodName("buyTickets"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); call.setParams(params); // Invoke Response res = call.invoke(new URL("http://rpc.middleearth.com"), ""); // Deal with the response
As you can see, the actual invocation itself, represented by the Call object, is resident in memory. It allows you to set the target of the call, the method to invoke, the encoding style, the parameters, and more not shown here. It is more flexible than the XML-RPC methodology, allowing you to explicitly set the various parameters that are determined implicitly in XML-RPC. You'll see quite a bit more about this invocation process in the rest of the chapter, including how SOAP provides fault responses, an error hierarchy, and of course the returned results from the call.
With that brief introduction, you probably know enough to want to get on with the fun stuff. Let me show you the SOAP implementation I'm going to use, explain why I made that choice, and get to some code.
Copyright © 2002 O'Reilly & Associates. All rights reserved.