 |
Apache SOAP Processing
One of the beauties of open source software is that any programmer can use the source
to perform debugging or add features. The limited documentation provided with many
open source packages, however, leaves the developer to make sense of the code with
only the source itself as a reference. For anything but a simple library or application,
this can be a sufficiently daunting task to discourage many programmers from working
with the source.
This document hopes to improve the situation, if only slightly, for programmers
interested in the source code for Apache SOAP. It does not go into detail, nor does
it use any standard for documentation, such as UML. Instead, this document provides
a textual outline of the steps performed on both the client and
server in processing a SOAP RPC call (this reads like
annotation accompanying a non-existent UML sequence diagram). The outlines are based on
the code for the SOAP 2.2 release.
Client
Client processing of a SOAP RPC call occurs within the invocation of the
Call#invoke method, which does the following (remember, some details are
omitted).
- Builds the request envelope by calling RPCMessage#buildEnvelope.
- Transmits the request by calling SOAPTransport#send.
- For SOAPHTTPConnection, this
- Creates the request as XML text by calling Envelope#marshall.
- Creates a Hashtable of HTTP headers.
- Creates a TransportMessage instance.
- Transmits the request by calling HTTPUtils#post.
- Reads the HTTP headers for the response by calling TransportMessage#getHeaders.
- Builds the response context, an instance of SOAPContext, by calling SOAPTransport#getResponseSOAPContext.
- Parses the response into a DOM by calling DocumentBuilder#parse.
- Creates an Envelope instance for the response by calling Envelope#unmarshall.
- Creates an AttributeHandler (which stores attributes and namespaces for the envelope) by calling AttributeHandler#unmarshall.
- Creates a Header (if there is a SOAP header in the envelope) by calling Header#unmarshall.
- Creates a Body (if there is a SOAP body in the envelope) by calling Body#unmarshall.
- Puts other XML nodes that are siblings to the body in a Vector.
- Gets a Response instance for the response by calling Response#extractFromEnvelope.
- Delegates to RPCMessage#extractFromEnvelope.
- Creates the Response by calling RPCMessage#unmarshall.
- Creates the return value as a Java class by calling SOAPMappingRegistry#unmarshall.
- Gets the deserializer by calling SOAPMappingRegistry#queryDeserializer.
- Creates the Java class instance by calling Deserializer#unmarshall.
- Creates output parameters as Java classes by calling SOAPMappingRegistry#unmarshall.
Note that the Apache SOAP server does not support output parameters, but the client does.
It is not difficult to add support for output parameters to the server; more than one post to the
soap-dev mailing list indicates someone having done this to their own installation.
- Gets the deserializer by calling SOAPMappingRegistry#queryDeserializer.
- Creates the Java class instance by calling Deserializer#unmarshall.
Return to top.
Server
Server processing of a SOAP RPC call occurs within the invocation of the
RPCRouterServlet#doPost method, which does the following (remember, some
details are omitted).
- Builds the request context, an instance of SOAPContext.
- Parses the SOAP envelope into an instance of Envelope by calling ServerHTTPUtils#readEnvelopeFromRequest.
- Delegates to ServerUtils#readEnvelopeFromInputStream.
- Creates an instance of TransportMessage.
- Parses the envelope by calling TransportMessage#unmarshall.
- Parses the XML by calling DocumentBuilder#parse.
- Creates the Envelope instance by calling Envelope#unmarshall.
- Creates an AttributeHandler (which stores attributes and namespaces for the envelope) by calling AttributeHandler#unmarshall.
- Creates a Header (if there is a SOAP header in the envelope) by calling Header#unmarshall.
- Creates a Body (if there is a SOAP body in the envelope) by calling Body#unmarshall.
- Puts other XML nodes that are siblings to the body in a Vector.
- Parses the SOAP RPC call into an instance of Call by calling RPCRouter#extractCallFromEnvelope.
- Verifies the target URI is known by calling ServiceManager#query.
- Creates the Call by calling Call#extractFromEnvelope.
- Delegates to RPCMessage#extractFromEnvelope.
- Creates the Call by calling RPCMessage#unmarshall.
- Creates a SOAPMappingRegistry by calling DeploymentDescriptor#buildSOAPMappingRegistry.
- Reads parameters from XML by calling DOMUtils#getNextSiblingElement.
- Creates parameters as Java classes by calling SOAPMappingRegistry#unmarshall.
- Gets the deserializer by calling SOAPMappingRegistry#queryDeserializer.
- Creates the Java class instance by calling Deserializer#unmarshall.
- Gets the deployment descriptor into an instance of DeploymentDescriptor based on the target URI of the call by calling ServiceManager#query.
Note that the target URI is specified by the id attribute of the isd:service element in the deployment descriptor XML file.
- Creates a provider (a subclass of Provider, such as RPCJavaProvider) based on the provider specified in the deployment descriptor.
The provider is specified by the type attribute of the isd:provider element in the deployment descriptor XML file.
- Finds the Java method to call by calling Provider#locate. The available methods and Java class are
specified by the deployment descriptor XML file.
- Confirms the method specified in the SOAP envelope is included in the deployment descriptor by calling RPCRouter#validCall.
- Gets the target Object instance by calling ServerHTTPUtils#getTargetObject.
- Gets the Java class name by calling DeploymentDescriptor#getProviderClass.
- Based on the scope specified in the deployment descriptor, either create a new instance or return a cached one.
- Invokes the Java method by calling Provider#invoke.
- Invokes the Java method by calling RPCRouter#invoke.
- Invokes the Java method by reflection.
- Creates a Parameter instance for the return value of the method.
- Creates a Response instance for the return envelope.
- Creates the SOAP response envelope XML by calling Response#buildEnvelope.
- Creates the SOAP response as XML text by calling Envelope#marshall.
- Creates an instance of TransportMessage initialized with the response context settings from Provider#invoke.
- Writes the response by calling TransportMessage#writeTo.
Return to top.
Resources
Apache SOAP Installation.
Return to top.
|