BUY THIS BOOK
Add to Cart

Print Book $39.95


Add to Cart

PDF $31.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £28.50

What is this?

Looking to Reprint or License this content?


Java and SOAP
Java and SOAP

By Robert Englander
Book Price: $39.95 USD
£28.50 GBP
PDF Price: $31.99

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Introduction
In the history of software development, new approaches frequently bring discarded ideas back into the mainstream of common practice. Each time an idea is revisited, prior successes and failures become invaluable aides in improving the concept and making its implementation better, or at least more usable. Now I'm not saying that we keep reinventing the wheel; rather, we keep going back and improving the wheel. And doing so can often be the catalyst for new ideas and new technologies that were not possible with the old wheel.
We've seen centralized computing with mainframes and their associated terminals come back disguised as application servers and thin clients. We've seen the concept of P-Code return in the form of interpreted languages like Java and Visual Basic. The universe of software development seems to expand and contract like, well, the cosmic Universe. If you wait around long enough, you may just be able to use the work you're doing today at some time in the future.
The point is, really, that a good idea is a good idea, regardless of whether it's a new idea. Timeliness is what matters most. So it goes for the world of distributed computing. The concept isn't new, but it gets revisited constantly. Pervasive infrastructure and technologies like the Internet, web browsers, and their associated protocols have allowed us to go back and advance the state of distributed computing. The evolution's latest craze is web services.
Web services are basically server functions that have published the interface mechanisms needed to access their capabilities. They're being implemented in a wide variety of technologies, but have a very important thing in common: they are providers of computational services that can be accessed using a standardized protocol. For instance, you might find a stock quote service that can return current stock market pricing and trading information based on a company's stock symbol. This is a very specific function, and that's the essence of web services. They do not provide the breadth of capability found in application servers — they provide small, focused capabilities that are likely to prove useful when combined with other services. You can imagine an online trading application that makes use of web services ranging from stock quotes to trade execution to banking transactions. The vision of web services is that it will ultimately be possible to create complex applications on the fly — or at least, with minimal development time — by combining bits and pieces of data and services that are distributed across the Web. Sun's slogan used to be "The network is the computer," and that vision is certainly coming to fruition.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
RPC and Message-Oriented Distributed Systems
Distributed systems exist, for the most part, as loosely coupled entities that communicate with each other to accomplish some task. One of the most common models used in distributed software is the remote procedure call (RPC). One reason for the popularity of RPC systems is that they closely resemble the function/method call syntax and semantics that we as programmers are so familiar with. Technologies like Java RMI, Microsoft's COM, and CORBA all use this kind of model. Of course, you have to jump through many hoops before making the ever-familiar method call to a remote system, but even with all that it still feels remarkably like making a local method call. Often, once the method call returns we don't care how it happened. Much of the work in providing that abstraction to programmers at the API level is what makes up the majority of the distributed systems implementations.
Another popular model for distributed computing is message passing. Unlike the RPC model, messaging does not emulate the syntax of programming language function calls. Instead, structured data messages are passed between parties. These messages can serve to decouple the nodes of the distributed system somewhat, and message-based systems often prove to be more flexible than RPC-based systems. However, that flexibility can sometimes be just enough rope for programmers to hang themselves.
It seems that a reasonable, and powerful, compromise might be to combine these two models. Can you imagine a system that provides for the familiarity and ease of use of RPC-style invocations, along with some of the flexibility of message-type systems? It seems to me that it would require the definition of a data format that could describe itself, while at the same time conforming to a standard set of rules governing that very description. Hmmm . . .
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Self-Describing Data
In programming parlance, the term self-describing data is itself self-describing. Put another way, if the question is, "What is self-describing data?" then the answer is, "Data that describes itself." Not a very useful definition. But that's the result of designing a flexible data format to be used by many, many people.
Let's look at a very simple example. Let's say we were designing a message-style distributed system for delivering stock quotes. We could design the response message format to be something like this:
  • The first 10 characters contain the stock symbol, right-padded with spaces
  • The next 10 characters represent the last price, right-padded with spaces
  • The next 10 characters represent the volume, right-padded with spaces
  • The next 20 characters represent the timestamp of the quote
  • The next 10 characters represent the bid price
  • The next 10 characters represent the ask price
You get the point. This is a fixed format message. It doesn't describe itself; rather it is described by the spec provided in the bullet list above. There's no flexibility here. And sometimes there's no need for any flexibility — it's not a one-size-fits-all scenario. But wouldn't you agree that there is some room for improvement? Let's consider the possibility that the values for last price, bid price, and ask price could be formatted in two different ways. The first format uses standard decimal notation, for example, 25.5. The other format uses fractions, so the same value would be encoded as 25 1/2. A self-describing format would have a provision for indicating which format is used for each of the price fields.
Now take this same concept and apply it to the overall structure of the message, as well as to its constituent parts. This gives you the flexibility to fully describe the contents of a message. For example, you could make some of the fields in the stock quote response optional. Maybe you've requested the quote after the market has closed, and maybe that renders the values for bid and ask prices useless. Then why return them at all? A self-describing format could specify its content, thereby having no need to return useless data.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
XML
We've all been staring a form of self-describing data in the face every time we use a web browser. HTML is a good example of a standard data format that is quite flexible due to its provision for self-describing elements. For example, the color and font to be applied to a particular section of text are described right along with the text itself. This kind of self-describing data is commonly referred to as a markup language. The content is "marked-up" with instructions for its own presentation. This is very nice, and it obviously has gained an incredible level of industry acceptance. But HTML is not flexible enough to accommodate content that was not anticipated by its designers. That's not a knock on HTML; it's just the truth. HTML is not extensible.
The Extensible Markup Language (XML) is just what we're looking for. XML is a hierarchical, tag-based language much like HTML. The important difference for us is that it is fully extensible. It allows us to describe content that is specific to our own applications in a standard way, without the designers of the language having anticipated that content. For example, XML would allow me to create content to represent the stock quote response message from the previous section. It defines the rules that I must follow in order to accomplish that task, without dictating a specific format.
I'm not going to spend any time covering XML itself. If you're not familiar with XML, you may want to remedy that before you begin reading Chapter 2. Many books have been published on XML and related topics. A good starting point for general information is XML in a Nutshell, by Elliotte Rusty Harold and W. Scott Means (O'Reilly). For Java developers, Java and XML by Brett McLaughlin (O'Reilly) should be of particular interest.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
API Specs Versus Wire-Level Specs
Java programmers are used to dealing with API-level specifications, where classes, interfaces, methods, and so on are clearly defined for the purpose of addressing a specific need. These specifications are designed to be independent of any specific implementation, focusing instead on the abstractions that must be implemented.
Consider the Java Message Service (JMS) specification. It fully describes the API that Java applications can use to access the features of message-oriented middleware (MOM) products. The motivation for a standard API is simple: if MOM vendors adopt the API, it becomes that much easier for programmers to work with the various product offerings. In theory, you could swap one JMS implementation for another without impacting the rest of your code. In practice, it means that product vendors might be somewhat handcuffed, unable to provide alternative APIs that leverage features and capabilities of their own products without sacrificing compliance. Nevertheless, API specifications have been around a long time, and they do achieve most of what they're intended to do.
However, the API specification approach, by itself, leaves a gaping hole in an extremely important area of software development: interoperability. You can't develop an application using Vendor A's JMS-compliant API to communicate with Vendor B's JMS-compliant server. The specification deals with only the API, not the format of the data being communicated between the parties. This seems to suggest that interoperability is not as important as commonality of programming syntax. Yes, it's a trade-off, but it's not always the right one.
A wire-level specification, on the other hand, deals exclusively in the content and format of the data being transmitted between parties: the data that's "on the wire." Instead of concentrating on APIs, it devotes itself to the representation used for distributed computing interactions. So you can pretty much guarantee that if you work with implementations from more than one vendor, the APIs will not be the same. However, you have a decent chance of getting distributed systems that were built using products from multiple vendors to work together. If you're doing any work in the area of web services, the wire-level specification approach is your ally; the API specification approach won't get you very far.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Overview of SOAP
One of the more recent forays into the world of distributed computing resulted in a wire-level specification called the Simple Object Access Protocol, or SOAP. The protocol is relatively lightweight, is based on XML, and is designed for the exchange of information in a distributed computing environment. There is no concept of a central server in SOAP; all nodes can be considered equals, or even peers.
The protocol is made up of a number of distinct parts. The first is the envelope, used to describe the content of a message and some clues on how to go about processing it. The second part consists of the rules for encoding instances of custom data types. This is one of the most critical parts of SOAP: its extensibility. The last part describes the application of the envelope and the data encoding rules for representing RPC calls and responses, including the use of HTTP as the underlying transport.
RPC-style distributed computing is the most common Java usage of SOAP today, but it is not the only one. Any transport can be used to carry SOAP messages, even though HTTP is the only one described in the specification. There has been significant discussion of using SMTP, BEEP, JXTA, and other protocols for carrying SOAP messages.
SOAP differs from RMI, CORBA, and COM in that it concentrates on the content, effectively decoupling itself from both implementation and underlying transport. An interesting concept for a Java book, wouldn't you say? After all, implementation and transport are likely to be built using Java. Yet SOAP in no way addresses Java or any other implementation strategy.
The reality is that SOAP is an enabler, incapable of existing on its own beyond the abstraction of the specification. To benefit from SOAP, or any other protocol, there have to be real implementations. Java is a great technology for implementing SOAP, and for building web services and applications that use SOAP as the "on the wire" data format.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
SOAP Implementations
As I write this book, there are dozens of SOAP implementations, and new ones emerge all the time. Some are implemented in Java, some aren't. Some are free, some aren't. And inevitably some are good, and some aren't. It would be impractical to do a side-by-side comparison of every available implementation or even to give equal coverage to them all. On the other hand, it wouldn't be wise to focus on a single implementation, since that would present a bias that I don't intend. A reasonable compromise, and the one I've elected to use, is to select two interesting Java SOAP implementations and use them both extensively throughout the book. This gives you an opportunity to see different APIs and programming strategies. In Chapter 9 and Chapter 11, I'll break this rule and look briefly at a couple of other important SOAP technologies.
The Apache Software Foundation has an ongoing project known as Apache SOAP. This is a Java implementation of the SOAP specification that can be hosted by servers that support Java servlets. The examples in this book are based on Apache SOAP Version 2.2, which is available at http://xml.apache.org/soap/index.html. Four very important factors led me to choose this implementation: it supports a good deal of the specification, it has a reasonably large user base, the source code is available, and it's free.
Although Apache SOAP can be hosted by a variety of server technologies, I've chosen Apache Tomcat (Version 3.3 and Version 4), available at http://jakarta.apache.org/tomcat/index.html. The reasons are not particularly tied to SOAP, but it does work well in Tomcat. The use of Tomcat has no real impact on the examples in the book, so you can feel free to select some other server technology if you like.
Apache SOAP was developed at a time when there were no standards for a SOAP API. The SOAP specification doesn't address language bindings, so the implementors were forced to come up with their own APIs. More recently, the Java community has been working on standards for SOAP-based messaging and RPC APIs, known as JAXM and JAX-RPC, respectively. We'll take a look at these APIs in Chapter 11; they will be implemented by Axis, which is the next-generation Apache SOAP implementation. In an ideal world, JAXM and JAX-RPC would have been completed in time for me to give them the coverage they deserve, since they will almost certainly replace the APIs developed for Apache SOAP 2.2. In reality, though, the standard APIs are just solidifying now, and should be in final form just in time to make me write a second edition earlier than I'd like. The bulk of this book will focus on technology that you can use to write production code now. Once you have the concepts down, moving to a different API will not be a challenge.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Approach
This book certainly does not cover every aspect of the SOAP technologies. My goal is to give you a good understanding of the major aspects of SOAP in the context of Java software development. You'll find that many of the examples are presented not only in Java source code, but also in the SOAP XML that is generated through the execution of the Java code. This will give you a sense of what the various APIs are actually accomplishing. Learning SOAP this way will allow you to go beyond the scope of this book with confidence, exploring the features and capabilities of the implementations I have covered as well those I have not.
One particular area is not covered in this book: security. How can you talk about a distributed computing technology without talking about security? The answer is actually quite simple: the SOAP specification does not deal with security. The current implementations rely on the security features of the hosting technology. Be it SSL, basic HTTP authentication, proxy authentication, or some other mechanism, all security is a function of the hosting technology and not part of SOAP itself. It's expected that either a future version of the SOAP spec or a separate SOAP Security spec will address that issue, but for now you'll have to rely on whatever your hosting technology supports.
The current spec does, however, mention the use of SOAP headers in security schemes, and you will find that some SOAP implementations follow that lead. Nonetheless, the mechanisms are likely to be specific to each implementation until a standard is adopted.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Getting Started
If you plan to work with the examples, you'll need to install all of the necessary software components, including the JDK, the SOAP implementations described earlier, and a number of other supporting technologies. All of these packages are reasonably well documented, so you should have no trouble getting them installed properly.
The chapters in this book are arranged so that each one builds on concepts of the preceding chapters. I suggest that you follow along in order, but of course that's entirely up to you. If you are already comfortable with XML or (even better) with some aspects of web services, you may find that you can jump around a bit.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: The SOAP Message
All SOAP messages are packaged in an XML document called an envelope, which is a structured container that holds one SOAP message. The metaphor is appropriate because you stuff everything you need to perform an operation into an envelope and send it to a recipient, who opens the envelope and reconstructs the original contents so that it can perform the operation you requested. The contents of the SOAP envelope conform to the SOAP specification, allowing the sender and the recipient to exchange messages in a language-neutral way: for example, the sender can be written in Python and the recipient can be written in Java or C#. Neither side cares how the other side is implemented because they agree on how to interpret the envelope. In this chapter we'll get inside the SOAP envelope.
The SOAP specification requires a SOAP implementation to support the transporting of SOAP XML payloads using HTTP, so it's no coincidence that the existing SOAP implementations all support HTTP. Of course, implementations are free to support any other transports as well, even though the spec doesn't describe them. There's nothing whatsoever about the SOAP payload that prohibits transporting messages over transports like SMTP, FTP, JMS, or even proprietary schemes; in fact, alternative transports are frequently discussed, and a few have been implemented. Nevertheless, since HTTP is the most prevalent SOAP transport to date, that's where we'll concentrate. Once you have a grasp of how SOAP binds to HTTP, you should be able to easily migrate your understanding to other transport mechanisms.
SOAP can certainly be used for request/response message exchanges like RPC, as well as inherently one-way exchanges like SMTP. The majority of Java-based SOAP implementations to date have implemented RPC-style messages, so that's where we'll spend most of our time; HTTP is a natural for an RPC-style exchange because it allows the request and response to occur as integral parts of a single transaction. However, one-way messaging shouldn't be overlooked, and nothing about HTTP prevents such an exchange. We'll look at one-way messaging in Chapter 8.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The HTTP Binding
The SOAP specification requires a SOAP implementation to support the transporting of SOAP XML payloads using HTTP, so it's no coincidence that the existing SOAP implementations all support HTTP. Of course, implementations are free to support any other transports as well, even though the spec doesn't describe them. There's nothing whatsoever about the SOAP payload that prohibits transporting messages over transports like SMTP, FTP, JMS, or even proprietary schemes; in fact, alternative transports are frequently discussed, and a few have been implemented. Nevertheless, since HTTP is the most prevalent SOAP transport to date, that's where we'll concentrate. Once you have a grasp of how SOAP binds to HTTP, you should be able to easily migrate your understanding to other transport mechanisms.
SOAP can certainly be used for request/response message exchanges like RPC, as well as inherently one-way exchanges like SMTP. The majority of Java-based SOAP implementations to date have implemented RPC-style messages, so that's where we'll spend most of our time; HTTP is a natural for an RPC-style exchange because it allows the request and response to occur as integral parts of a single transaction. However, one-way messaging shouldn't be overlooked, and nothing about HTTP prevents such an exchange. We'll look at one-way messaging in Chapter 8.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
HTTP Request
The first SOAP message we'll look at is an RPC request. Although it's rather simple, it contains all of the elements required for a fully compliant SOAP message using an HTTP transport. The XML payload of the message is contained in an HTTP POST request. Take a quick look, but don't get too caught up in figuring out the details just yet. The following message asks the server to return the current temperature in degrees Celsius at the server's location:
POST /LocalWeather HTTP/1.0
Host: www.mindstrm.com
Content-Type: text/xml; charset="utf-8"
Content-Length: 328
SOAPAction: "WeatherStation"
  
<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:GetCurrentTemperature xmlns:m="WeatherStation">
         <m:scale>Celsius</m:scale>
    </m:GetCurrentTemperature>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The SOAP HTTP request uses the HTTP POST method. Although a SOAP payload could be transported using some other method such as an HTTP GET, the HTTP binding defined in the SOAP specification requires the use of the POST method. The POST also specifies the name of the service being accessed. In the example, we're sending the data to /LocalWeather at the host specified later in the HTTP header. This tells the server how to route the request within its own processing space. Finally, our example indicates that we're using HTTP Version 1.0, although SOAP doesn't require a particular version of HTTP.
The Host: header field specifies the address of the server to which we're sending this request, www.mindstrm.com. The next header field, Content-Type:, tells the server that we're sending data using the text/xml media type. All SOAP messages must be sent using text/xml. The content type in the example also specifies that the data is encoded using the UTF-8 character set. The SOAP standard doesn't require any particular encoding. Content-Length: tells the server the character count of the POSTed SOAP XML payload data to follow.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
HTTP Response
An RPC-style request message usually results in a corresponding HTTP response. Of course, if the server can't get past the information in the HTTP headers, it can reply with an HTTP error of some kind. But assuming that the headers are processed correctly, the system is expected to respond with a SOAP response. Here's the HTTP response to the RPC-style request from the previous example:
HTTP/1.0 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: 359
  
<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:GetCurrentTemperatureResponse xmlns:m="WeatherStation">
           <m:temperature>26.6</m:temperature>
     </m:GetCurrentTemperatureResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The response's HTTP header fields are, for the most part, similar to those of the request. The response code of 200 in the first line of the header indicates that the server was able to process the SOAP XML payload. The Content-Type: and Content-Length: fields have the same meanings as they did in the request message. No other HTTP header fields are needed; the correlation between the request and response is implied by the fact that the HTTP POST is inherently a request/response mechanism. You send the request and get the response as part of a single transaction.
Let's change the original request message so that the scale reads as follows:
<m:scale>Calcium</m:scale>
You know that one, right? No, there is no Calcium scale for temperature; we've constructed an erroneous request. So we go ahead and send the SOAP request to the server. Assuming the weather station hasn't really fallen off the building, the server processes the request. As we expected, our SOAP processing code does not understand the Calcium temperature scale, and generates the following error response:
HTTP/1.0 500 Internal Server Error
Content-Type: text/xml; charset="utf-8"
Content-Length: 525
  
<SOAP-ENV:Envelope 
          xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Client</faultcode>
         <faultstring>Client Error</faultstring>
         <detail>
            <m:weatherfaultdetails xmlns:m="WeatherStation">
               <message>No such temperature scale: Calcium</message>
               <errorcode>1234</errorcode>
            </m:weatherfaultdetails>
         </detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The SOAP Envelope
The SOAP envelope represents the entirety of the XML for a SOAP request or response. The Envelope is the highest-level XML element in the message, and it must be present for the message to be considered valid. So in essence, the Envelope represents the XML document that contains the SOAP message. The Envelope can contain an optional Header element that, if present, has to be the first subelement of the Envelope. The Envelope must contain a Body element. If the Envelope contains a Header element, then the Body element has to come right after the Header; otherwise the Body has to be the first subelement of the Envelope.
A SOAP envelope packaged and transported using HTTP is similar to a paper envelope sent using the postal service. The SOAP envelope is the paper envelope; the SOAP header (if present) and the SOAP body are the contents of the paper envelope; and the HTTP headers are the physical address information on the outside of the paper envelope.
With a little imagination we can complete the analogy. The return address on a paper envelope has no direct counterpart in the SOAP process; however, in both cases an undeliverable message is returned to sender. The only thing missing is the stamp. I guess this is where the analogy may break down a little. Still, although you probably don't pay specifically for sending an HTTP request to a server, you're probably paying for Internet service. So there's your postage stamp!
Understanding XML namespaces is important to understanding SOAP. I'm not going to cover all the details of XML namespaces, as that would take a long time and wouldn't reflect directly on the subject matter of this book. Nonetheless, I'll give you a quick description of XML namespaces as they relate to SOAP. Basically, namespaces are an XML mechanism for eliminating ambiguity between XML elements and attributes. In other words, they help us to understand the context, or meaning, of the element. Let's look at part of an earlier example:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Envelope Element
The Envelope is the topmost element of the XML document that represents the SOAP message. The Envelope is the only XML element at the top level; the rest of the SOAP message resides within the Envelope, encoded as subelements. A SOAP message must have an Envelope element. The Envelope can have namespace declarations, as shown in the earlier examples, and needs to be qualified as shown earlier, using the http://schemas.xmlsoap.org/soap/envelope namespace. That's why the element name is shown as SOAP-ENV:Envelope. It is also common for the Envelope element to declare the encodingStyle attribute, with the attribute namespace-qualified using the declared namespace identifier SOAP-ENV as well.
All subelements and attributes of the Envelope must themselves be namespace-qualified. These elements and attributes are also qualified by SOAP-ENV, just as the Envelope is qualified. For the remainder of this chapter and the rest of the book, we'll use the SOAP-ENV namespace identifier to mean the http://schemas.xmlsoap.org/soap/envelope namespace. This should make for easier reading. Keep in mind that it's the namespace itself that matters, not the name used for the qualifier.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Header Element
The SOAP header is optional. If it is present, it must be named Header and be the first subelement of the Envelope element. The Header element is also namespace-qualified using the SOAP-ENV identifier.
Most commonly, the Header entries are used to encode elements used for transaction processing, authentication, or other information related to the processing or routing of the message. This is useful because, as we'll see, the Body element is used for encoding the information that represents an RPC (or other) payload. The Header is an extension mechanism that allows any kind of information that lies outside the semantics of the message in the Body, but is nevertheless useful or even necessary for processing the message properly.
Header elements should limit the use of attributes to those elements that are immediate children of the Header element itself. The spec says that this should be done, meaning that although one can use them on elements deeper in the element hierarchy underneath the Header element, the recipient is required to ignore the attributes on such elements.
Here's an example of a SOAP header that contains an immediate child element named username. We don't apply any attributes to the username element, but we do namespace-qualify it. The username element identifies the user who is making the request.
<SOAP-ENV:Header>
    <ns1:username xmlns:ns1="JavaSoapBook">
      Jessica
    </ns1:username>
</SOAP-ENV:Header>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The actor Attribute
A SOAP message often passes through one or more intermediaries before being processed. For example, a SOAP proxy service may stand between a client application and the target SOAP service. We'll see an interesting example of this in Chapter 10, where we'll develop a SOAP application service that proxies another service on behalf of the client application, which actually specifies the ultimate service address. Therefore, the header may contain information intended solely for the intermediary as well as information intended for the ultimate destination. The actor attribute identifies (either implicitly or explicitly) the intended recipient of a Header element.
It's important to understand the requirements that SOAP puts on an intermediary. Essentially, it requires that any SOAP Header elements intended for use by an intermediary are not passed on to the next SOAP processor in the path. Header elements represent contracts between the sender and receiver. However, if the information contained in a Header element intended for an intermediary is also needed by a downstream server, the intermediary can insert the appropriate Header in the message to be sent downstream. In fact, the intermediary is free to add any Header elements it deems necessary.
If an actor attribute doesn't appear on a Header element, it's assumed that the element is intended for the ultimate recipient. In essence, this is equivalent to including the actor attribute with its value being the URI of the ultimate destination.
Let's extend the previous example by adding an actor attribute. Say that the message is being sent to an intermediate application server located at http://www.mindstrm.com/AppServer. We want that application server to log the name of the user that made the request, and then pass the request on to the final destination server. To do so, we set the actor for the username element to http://www.mindstrm.com/AppServer:
<SOAP-ENV:Header>
   <ns1:username 
         xmlns:ns1="JavaSoapBook"
         SOAP-ENV:actor="http://www.mindstrm.com/AppServer">
         Jessica
    </ns1:username>
</SOAP-ENV:Header>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The mustUnderstand Attribute
SOAP includes the concept of optional and mandatory header elements. This doesn't mean that the inclusion of the elements is mandatory — that is an application issue. Instead, "mandatory" means that the recipient is required to understand and make proper use of the information supplied by a Header element. This requirement allows us to accommodate situations in which a recipient of a SOAP message can't perform its job unless it knows what to do with the data provided by a specific Header element. In this case the element can include the mustUnderstand attribute with an assigned value of 1.
This may be necessary if the sending application is upgraded with a new version, for example. That new version may use some new information that has to be processed by the server in order for the result to be useful. Of course you'd expect that there would be a corresponding upgrade to the server, but maybe that hasn't happened yet. Because of the version mismatch, the older version of the server does not understand the new SOAP header element that it received from the upgraded client application. Let's say, for example, that the username header element must be understood by the recipient; if it is not, the message should be rejected. We can include this requirement in the SOAP message by assigning the mustUnderstand attribute the value of 1. (The value 0 is essentially equivalent to not supplying the attribute.) Let's modify our previous example to indicate that the recipient must understand the username element:
<SOAP-ENV:Header>
    <ns1:username 
        xmlns:ns1="JavaSoapBook"
        SOAP-ENV:actor="http://www.mindstrm.com/AppServer"
        SOAP-ENV:mustUnderstand="1">
        Jessica
    </ns1:username>
</SOAP-ENV:Header>
If the recipient of this message does not understand the username element, it is required to respond with a SOAP fault. The response might look something like this:
HTTP/1.0 500 Internal Server Error
Content-Type: text/xml; charset="utf-8"
Content-Length: 373
  
<SOAP-ENV:Envelope 
          xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:MustUnderstand</faultcode>
         <faultstring>SOAP Must Understand Error</faultstring>
         <faultactor>http://www.mindstrm.com/AppServer</faultactor>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The encodingStyle Attribute
The encodingStyle attribute specifies the data encoding rules used to serialize and deserialize data elements. It is important to understand that SOAP does not specify any default rules for data serialization. SOAP does, however, specify a simple data typing scheme commonly supported by SOAP implementations. This is the subject of the next chapter, so we won't get into the details of the encoding rules here. However, it's important to understand how to specify the encoding style to be used for serializing and deserializing the element data in the SOAP message.
The encodingStyle attribute is namespace-qualified using the SOAP-ENV namespace identifier. In the following example we specify the encodingStyle attribute as part of the Envelope element; we'll see examples in later chapters that make this declaration in the Body element instead. Either way works, as long as you recognize that the encodingStyle attribute applies to the element in which it was declared as well as all of its subelements (i.e., it's in-scope).
<SOAP-ENV:Envelope 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    . . .
    . . .
</SOAP-ENV:Envelope>
You can supply more than one URI in the declaration. In that case, the first URI must be the most specific, and the last must be the least specific. Here's an example:
SOAP-ENV:encodingStyle="http://www.mindstrm.com/tightEncoding 
http://www.mindstrm.com/looseEncoding"
In this case, the system looks for the encoding rules first using http://www.mindstrm.com/tightEncoding. If the rule can't be found using that URI, the system then tries http://www.mindstrm.com/looseEncoding. It's possible to turn off the currently scoped encoding style by specifying an empty string for the URI (""). This declaration applies to the current element and all of its subelements.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Envelope Versioning
The SOAP spec doesn't define a numbering system for declaring which version of the SOAP envelope you're using. In SOAP 1.1, all envelopes must be associated with the http://schemas.xmlsoap.org/soap/envelope namespace, which we've used in all of the previous examples. That's it. No other versioning information is used for SOAP envelopes at this time. If a SOAP message is associated with any other namespace, or if no namespace is declared, then the recipient has to respond with a SOAP version mismatch. Here is an example of a SOAP fault response for this situation:
HTTP/1.0 500 Internal Server Error
Content-Type: text/xml; charset="utf-8"
Content-Length: 311
  
<SOAP-ENV:Envelope 
          xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:VersionMismatch</faultcode>
         <faultstring>SOAP Envelope Version Mismatch</faultstring>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Body Element
The SOAP Body element is mandatory in SOAP 1.1. If there is no SOAP header, the Body must be the first subelement of the Envelope; otherwise it must directly follow the SOAP Header element. The Body element is also namespace-qualified using the SOAP-ENV identifier.
The Body element contains the SOAP request or response. This is where you might find an RPC-style message that contains the method name and its parameters, or a one-way message and its relevant parts, or a fault and its details. SOAP Body elements are not completely defined by the SOAP specification; we'll cover that subject in great detail later. In fact, SOAP defines only one kind of Body: the SOAP Fault.
Let's take another look at one of the earlier examples of an envelope with a SOAP Body element. In this case the request is an RPC. We've namespace-qualified the Body element using the same SOAP-ENV namespace identifier that we used for the other SOAP-defined elements and attributes.
<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:GetCurrentTemperature xmlns:m="WeatherStation">
                <m:scale>Celsius</m:scale>
         </m:GetCurrentTemperature>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
SOAP Faults
The Fault is the only Body element entry defined by SOAP. It's used to carry error information back to the originator of a SOAP message. The Fault element must appear as an immediate subelement of the Body element, and it can't appear more than once.
SOAP defines four subelements of the Fault element. Not all of these are required, and some are appropriate only under certain conditions. These elements are described in the following sections. You'll probably recognize that we've seen all of these in previous examples, so you may want to flip back and look at them again after you've read these descriptions.
The faultcode element provides an indication of the fault that is recognizable by a software process, providing an opportunity for the system receiving the fault to act appropriately. The code is not necessarily useful to humans — that is the purpose of the faultstring element described in the next section. The faultcode element is mandatory, and must appear as a subelement of the Fault element. SOAP defines a number of fault codes for use in the faultcode element. These codes are associated with the http://schemas.xmlsoap.org/soap/envelope namespace. Here are brief descriptions of the SOAP-defined fault codes:
VersionMismatch
Indicates that an invalid namespace was associated with the SOAP Envelope.
MustUnderstand
Means that there was a SOAP Header element that contained the mustUnderstand attribute with a value of 1, and either the attribute was not understood or the semantics associated with the attribute couldn't be followed.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: SOAP Data Encoding
When sending data over a network, the data must comply with the underlying transmission protocol, and be formatted in such a way that both the sending and receiving parties understand its meaning. This is what we refer to as data encoding. Data encoding encompasses the organization of the data structure, the type of data transferred, and of course the data's value. Just like in Java, it is the data that gets serialized, not the behavior. Data encoding and serialization rules help the parties involved in a SOAP transaction to understand the meaning and content of the message. The model for SOAP encoding is based on XML data encoding, but the encoding constrains or alters those rules to fit the intended purpose of SOAP. I think you'll find that the data requirements of most systems can be easily represented using the encoding rules presented here.
Namespaces provide the mechanism used to determine how element and attribute names are interpreted. Because XML allows arbitrary element names, it needs a mechanism for specifying which dictionary should be used to look up the meaning of any given name. The encoding style defined in section 5 of the SOAP specification is the most commonly used encoding style in SOAP. This encoding style, which is defined in the schema referenced by the http://schemas.xmlsoap.org/encoding namespace, is often referred to as "SOAP Section 5." In SOAP messages, this namespace is by convention referenced using a namespace qualifier such as SOAP-ENC or soapenc. In our examples we will use the SOAP-ENC namespace qualifier to refer to this namespace.
It's important to understand that, in SOAP, schemas are used as references to definitions of data elements. They aren't used to validate SOAP message data in standard SOAP processing, although there's nothing stopping you from doing that on your own. References to schemas are often used as namespaces in order to qualify a serialized data element. It's up to the developer or the underlying framework to understand the structure or meaning of the data and to code to it accordingly.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Schemas and Namespaces
Namespaces provide the mechanism used to determine how element and attribute names are interpreted. Because XML allows arbitrary element names, it needs a mechanism for specifying which dictionary should be used to look up the meaning of any given name. The encoding style defined in section 5 of the SOAP specification is the most commonly used encoding style in SOAP. This encoding style, which is defined in the schema referenced by the http://schemas.xmlsoap.org/encoding namespace, is often referred to as "SOAP Section 5." In SOAP messages, this namespace is by convention referenced using a namespace qualifier such as SOAP-ENC or soapenc. In our examples we will use the SOAP-ENC namespace qualifier to refer to this namespace.
It's important to understand that, in SOAP, schemas are used as references to definitions of data elements. They aren't used to validate SOAP message data in standard SOAP processing, although there's nothing stopping you from doing that on your own. References to schemas are often used as namespaces in order to qualify a serialized data element. It's up to the developer or the underlying framework to understand the structure or meaning of the data and to code to it accordingly.
SOAP Section 5 incorporates all of the built-in data types of XML Schema Part 2: Datatypes. This schema defines most of the basic data types you'll use, either directly or as part of your own types. The general practice is to declare a namespace identifier named xsd and associate it with the namespace http://www.w3.org/2001/XMLSchema. As we saw in the previous chapter, this declaration is usually done as an attribute of the SOAP Envelope or SOAP Body.
Another common namespace identifier used for data encoding is xsi, which is associated with the namespace http://www.w3.org/2001/XMLSchema/instance. The easiest way to explain this identifier is with an example. Imagine that we want to declare that the data type of a particular XML element is a
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Serialization Rules
The XML elements in a SOAP message are either independent or embedded. Because of the hierarchical nature of XML, most elements are embedded as subelements of other elements. Independent elements, then, are not subelements of any other elements; they appear at the top level of a serialization.
All of the values in a SOAP message are encoded as the content of an element. Data values cannot appear by themselves outside the confines of an element. That does not mean, however, that every XML element contains a value. For instance, compound data types like structs or arrays contain subelements that contain the actual data values. The elements that define these compound data values do not contain the data directly. Compound types will be covered a little later.
SOAP Section 5 also permits elements to reference the values contained in other elements. In this case, no value is provided with the element; instead, an attribute identifies the element in which the actual data value is to be found. The data value must be contained in an independent element, appearing at the top level of a serialization.
The element containing the data value must contain an attribute named id of type ID. The value of the id attribute is the name that other elements use to reference the value. Here is such an element:
<lastName id="name-1">Englander</lastName>
The lastName element is a perfectly valid accessor in its own right. In addition, it has an identifier that allows other elements to reference the data value.
Elements that access a value in another element have no data values themselves. They are empty elements containing an href attribute that references the value. The href attribute is of type uri-reference defined in the XML Schema specification; the value of this attribute references the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Indicating Type
Every element that contains a value must also indicate the type of the data. There are a few different ways to indicate the data type. The first mechanism is to include an xsi:type attribute as part of the element. This means that the attribute is named type, as defined by the namespace indicated by xsi. The value assigned to xsi:type must be a valid type identifier such as xsd:float, xsd:string, etc. In the second mechanism, the value can be an element of an array that already constrains the type of its constituent parts to a particular data type. In this case, no explicit type declaration for the individual values is necessary; we'll see this later when we talk about arrays. Finally, the element name itself can be related to some type that can be determined by looking at the associated XML schema. The following extract from an XML schema defines a compound data type:
<element name="Automobile" type="Automobile"/>
<complexType name="Automobile">
     <element name="make" type="xsd:string"/>
     <element name="model" type="xsd:string"/>
     <element name="year" type="xsd:int"/>
</complexType>
The data type Automobile contains elements named make and model of type string, as well as a year of type int. Now let's look at an instance of type Automobile based on this schema:
<niceCar xsi:type="Automobile" >
    <model>Corvette</model>
<make>Chevrolet</make>
    <year>1999</year>
</niceCar>
This XML defines an instance of type Automobile: a 1999 Chevrolet Corvette. Because the schema for the Automobile type already specifies the data types for the constituent parts, we don't need to declare the types in the example.
SOAP makes use of the simple types as defined in the XML Schema Part 2: Datatypes, in the section called "Built-in datatypes." That section of the specification talks about integers, floats, strings, etc., as well as a variety of data types derived from the base types. For instance, a
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Default Values
Content preview·Buy