Apache SOAP uses type mappings to determine
how Java datatypes should be marshalled to/unmarshalled
from XML so that they can be transmitted
on/received from the wire. The type mappings
are stored in a type mapping registry, with
the default registry being org.apache.soap.encoding.SOAPMappingRegistry.
Each type mapping carries several pieces
of information: a URI describing the encoding
style (i.e. http://schemas.xmlsoap.org/soap/encoding/,)
a qualified name (QName) for the XML element
(i.e. http://www.w3.org/2001/XMLSchema:int,)
the Java class to be encoded from/decoded
to, the name of the Java class to act as
the serializer, and the name of the Java
class to act as the deserializer. The Java
classes acting as serializers/deserializers
must implement org.apache.soap.util.xml.Serializer
and org.apache.soap.util.xml.Deserializer,
respectively.
To make life a little easier, a set of type mappings has been predefined and registered into the SOAPMappingRegistry for the SOAP encoding style. These include mappings for the following Java types:
The SOAPMappingRegistry also provides a type mapping to encode org.apache.soap.rpc.Parameters in the literal XML encoding style, and a set of mappings to encode types supported by the IBM XMI Framework in the XMI encoding style.
If you want to pass your own objects as parameters to SOAP RPC services, then you will need to register new type mappings (and possibly create your own serializers/deserializers.) Remember that you will need to register the new type mappings on both the server and the client sides.
There are two main ways to register type mapping information into an Apache SOAP server:
The first way is probably the easiest to implement and manage, but it does require that you replicate the mapping information in each deployment descriptor that needs it. For more information on registering type mapping information via a deployment descriptor, look here.
The second mechanism requires a little more work, but allows you to limit the amount of additional information that you need to put into each deployment descriptor. In addition, the same mapping registry may be used on the client side, and thus may cut down on the amount of additional code that must be written for the client. The new registry must be a subclass of the SOAPMappingRegistry. For information about overriding the default mapping registry, look here.
As is the case with the server, on the client there are also two main ways to register type mapping information:
The first way is probably the easiest to
do, but if you have to use the same type
mappings in multiple different clients or
if you are also implementing the server-side
as well, then the second method may save
you a little bit of coding. The following code from
GetAddress.java
in the addressbook sample shows
an example of mapping two classes that follow the Java Bean
pattern.
SOAPMappingRegistry smr = new SOAPMappingRegistry();
BeanSerializer beanSer = new BeanSerializer();
// Map the types.
smr.mapTypes(Constants.NS_URI_SOAP_ENC,
new QName("urn:xml-soap-address-demo", "address"),
Address.class, beanSer, beanSer);
smr.mapTypes(Constants.NS_URI_SOAP_ENC,
new QName("urn:xml-soap-address-demo", "phone"),
PhoneNumber.class, beanSer, beanSer);
// Build the call.
Call call = new Call();
call.setSOAPMappingRegistry(smr);
In many cases, even if there is not a default
type mapping for the object that you are
trying to transmit, you still may not need
to create a new serializer/deserializer.
Apache SOAP comes with a Java Bean Serializer/Deserializer
that may suit your needs. The org.apache.soap.encoding.soapenc.BeanSerializer
can be used to serialize and deserialize
JavaBeans using the SOAP encoding style.
The public properties of the bean will become
named accessors (elements) in the XML form.
To use the BeanSerializer, simply pass "org.apache.soap.encoding.soapenc.BeanSerializer"
as the last two parameters when you are registering
the type mapping for your object.
Note: The object that you are serializing
with the BeanSerializer MUST be a JavaBean for this serializer to work:
This is NOT a general/all-purpose serializer. It WILL NOT work if the object which you are serializing/deserializing does not conform to the JavaBeans definition. It is NOT a bug if you cannot serialize/deserialize your non-Bean, Java class with this, any more than it is a bug that you can't serialize a java.awt.Panel with the java.util.Date serializer.
If you need to create a new serializer/deserializer, then looking at the source code for the predefined ones will probably provide you with the best guidance. Remember that they will need to implement org.apache.soap.util.xml.Serializer and org.apache.soap.util.xml.Deserializer respectively. You can implement them both in the same class, or use two different classes, it really makes no difference.
Last updated 5/21/2001 by Bill Nagy <nagy@watson.ibm.com>.