Whereas JAX-RPC is concerned with allowing a client program to make a remote procedure call to a web service without exposing the underlying XML-based protocols that are used, SAAJ is a much lower-level API that is entirely concerned with the messages exchanged between the web service and its clients. Furthermore, while JAX-RPC applications look, for the most part, like ordinary Java applications making local method calls, an application that uses SAAJ needs to construct SOAP messages piece by piece and extract information from response messages. Using SAAJ requires much more work on the part of the developer than JAX-RPC, so why would you bother to use it? Here are some of the circumstances in which you might want to use SAAJ and its close relative JAXM instead of JAX-RPC:
JAX-RPC is convenient for accessing web services that present an RPC-like interface. However, the RPC model is not suitable for all services. In many cases, it is more convenient to simply send an XML message to a service, which the service interprets and then generates an XML response. The most commonly quoted example of this is a business-to-business service where the client sends a purchase order in the form of an XML document to which the service responds with a confirmation and an invoice, also encoded as an XML document. A simple service like this does not require method calls or arguments � all that is necessary is to exchange fragments of XML. SAAJ represents a convenient way to encode and decode the SOAP messages that will carry these XML documents.
Most services accessed using JAX-RPC are likely to be synchronous in nature, so that the service immediately processes the request and returns a reply to the client, which is blocked until the call completes. However, it is not always convenient or appropriate for the service to handle the request and reply immediately. Using the purchase order example again, the business that receives the purchase order may not be able to respond with a confirmation or an invoice immediately � perhaps not until the goods are in stock, or until it is verified that the initiator of the request has an account against which the goods can be ordered and that sufficient credit is available. For this type of business model, which is likely to be very common in the real world, it is more appropriate to think of the whole process as two separate operations that are not tightly coupled to each other and that the responding business might take anything from several seconds to several days to reply. To implement this type of loosely coupled messaging, it is appropriate to use JAXM, which is built on top of SAAJ and provides the ability to send and receive messages asynchronously.
JAX-RPC works only when the client and the service are active at the same time and also assumes that there is an available network path that directly connects them. If the service is not available when the client initiates the request, or there are good reasons (perhaps security-related) why the client cannot be directly connected to the server, then you can't use JAX-RPC. JAXM, on the other hand, provides a reliable delivery service without requiring the client application to be involved in how the reliability is provided and can also support routing of SOAP messages between hosts that cannot be directly connected.
SAAJ and JAXM provide a complete solution for XML-based messaging. The major differences between SAAJ and JAXM are as follows:
SAAJ provides the API for the generic handling of SOAP messages; JAXM builds on this by adding the capability to create SOAP messages with preset content as required by messaging standards such as SOAP-RP and ebXML-TRP.
SAAJ can be used to create a freestanding Java client that communicates directly with a web service. JAXM adds the concept of a messaging provider, which acts as an intermediary between the client and the eventual recipient of the message. The message provider can provide a reliable delivery service and can route messages to other intermediaries without the involvement of the client. JAXM clients that use a messaging provider must be hosted in a web container or an application server.
SAAJ clients (and JAXM clients that choose not to use a messaging provider) can only engage in synchronous request/response message exchanges. However, JAXM clients using a messaging provider have access to additional message exchange modes, including asynchronous delivery and receipt of messages. See Chapter 4 for further details.
The classes and interfaces that provide the SAAJ and JAXM APIs reside in different packages, and, to emphasize the fact that SAAJ does not require JAXM, they are distributed in separate JAR files, as shown in Table 3-1.
API |
Package |
JAR file |
---|---|---|
SAAJ |
saaj-api.jar (API) saaj-ri.jar (reference implementation) |
|
JAXM |
jaxm-api.jar (API) jaxm-runtime.jar (reference implementation) |
In the case of J2EE 1.4, JAXM is not supported and the SAAJ classes appear in lib\j2ee.jar, which contains almost all of the packages in the reference implementation.
Although we have used the terms "client" and "server" to describe the participants in a SAAJ message exchange, the programming model for both SAAJ and JAXM does not make a strong distinction between these two roles, because most of the API is concerned with the details of handling the messages rather than actually sending and receiving them. In fact, SAAJ messaging represents more of a peer-to-peer model in which it might be more appropriate to use the terms "sender" and "receiver" instead of "client" and "server." In this chapter, however, all of the examples use SAAJ and are therefore limited to synchronous request/reply exchanges. For the sake of clarity, I will continue to use the term "client" to refer to the initiator of a service request, which will always be a freestanding J2SE application, and I will use "server" to mean the entity that receives and replies to the request.
For the JWSDP, to compile client applications that use SAAJ, your CLASSPATH needs to include only the saaj-api.jar file. However, the CLASSPATH required to run a client application is much larger, consisting of the following JAR files, which can be found in various subdirectories of the JWSDP installation:
saaj-api.jar |
saaj-ri.jar |
activation.jar |
commons-logging.jar |
dom4j.jar |
mail.jar |
jaxp-api.jar |
dom.jar |
sax.jar |
xalan.jar |
xercesImpl.jar |
xsltc.jar |
To run a SAAJ client application with J2EE 1.4, your CLASSPATH needs to include lib\j2ee.jar, together with the following four files from the endorsed directory:
dom.jar |
sax.jar |
xalan.jar |
xercesImpl.jar |
Aside from the handling of SOAP messages, SAAJ includes the ability to synchronously send a completed message to a given destination using HTTP as the underlying transport mechanism[1] and receive the reply (see Section 3.3.1, later in this chapter), but no specific provision is made for receiving a SOAP request in the server role. Servers are expected to reside in web containers or application servers, and need to make their own arrangements to receive SOAP messages. The JAXM specification includes a servlet (javax.xml.messaging.JAXMServlet) that can be used as the basis for a web container-based message receiver, but service providers are not required to use it. The example source code in this chapter uses a servlet that is very similar to JAXMServlet, so that we can demonstrate SAAJ without introducing a dependency on JAXM. This servlet is described later in this chapter in Section 3.3.2.
[1] Support of HTTP as the transport mechanism for SOAP messages is mandatory for all SAAJ implementations. Vendors are free to provide other transport mechanisms, but are not required to do so.