Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 7
The org.apache.soap.rpc package provides support for performing RPC over SOAP in Apache SOAP. The central concept behind Apache SOAP's RPC support
is that of an object ID. All Apache SOAP services must have a unique ID that acts as the service's object ID. As always, uniqueness
is relative; in Apache SOAP, the uniqueness of these object IDs is related to the Apache SOAP server on which a service is
deployed. That is, two services deployed on different Apache SOAP servers might have the same object ID.
A client interested in using a service sets up an org.apache.soap.rpc.Call object with the desired service's object ID, the name of the method to be invoked, and the parameters (if any) for that method.
Once the Call object is set up, the client calls its invoke() method, which takes two parameters. The first is a URL to the rpcrouter servlet; in this case, the URL is http://localhost:8080/apache-soap/servlet/rpcrouter. The second parameter is the SOAPAction header. Refer to Part 1 for a refresher on the importance of the SOAPAction header and its possible values.
The invoke() method converts the Call object into an XML SOAP request (which is similar to the examples in Part 1) and sends that request to the rpcrouter servlet, as indicated by the URL. When the servlet returns a response, the invoke() method returns an org.apache.soap.rpc.Response object, which contains the service response (if any) or the fault (if a fault was generated). HTTP dictates that every request
must have a response; so even if the service itself does not return anything, the rpcrouter servlet always does. Hence, the invoke() method will always return a Response object.
On the service side, the Apache SOAP server -- that is, the rpcrouter servlet -- receives the POSTed SOAP request from the client and rebuilds a Call object. The servlet uses the object ID from the rebuilt Call object to locate the object in the service manager.
The servlet then verifies the method name and invokes it on the located object. The servlet also serializes the return value from this call and sends it back in the HTTP response.
The above discussion raises an interesting question: How does Apache SOAP know how to serialize a given data type? Apache
SOAP handles the marshalling and unmarshalling of Java data types to and from XML via a type-mapping registry (org.apache.soap.encoding.SOAPMappingRegistry), and via serialization (org.apache.soap.util.xml.Serializer) and deserialization (org.apache.soap.util.xml.Deserialization) interfaces that all marshallers and unmarshallers, respectively, must implement. Apache SOAP provides a number of built-in
marshallers and unmarshallers that implement these interfaces. For example, you can use the org.apache.soap.encoding.soapenc.BeanSerializer class to marshall and unmarshall JavaBeans. I will show you how to use that class later in this article.
Serializers and deserializers for the Java primitive types (int, long, double, etc.) and their objectified forms (Integer, Long, Double, etc.) are preregistered in the type-mapping registry. Therefore, using Java primitives and their objectified forms as method
parameters is seamless to a client. However, if a service method requires a parameter that is a JavaBean, it must manually
register the BeanSerializer with the type-mapping registry. The service never performs any extra work; the client always ends up doing more. In Part
4 of this series, I will introduce you to a framework built using dynamic proxies, which will make creating clients just as
easy as creating services.