Using SOAP with Java | Binary Data Types

Binary data-types

Apache SOAP implementation also allows you to send binary-data in one of the following forms

  • Byte arrays
  • Hexadecimal Strings
  • MIME attachments

The Hexadecimal Strings are encoded with org.apache.soap.encoding.Hex wrappers object and this is the class that gets De-serialized. The Apache SOAP implementation supports embedding a SOAP envelope within a MIME type, and binary data then can be carried as a MIME attachment.

Serialization and Deserialization mechanism in Apache SOAP

With the above concept in mind, now it is time to look at how exactly Apache SOAP handles the (De-)Serialization of data-types. In order to make the (De-)Serialization work the Apache SOAP relies on a type mapping registry which defines the (De-)Serializers and maps them against different data-types. This registry is an instance of the class org.apache.soap.encoding.SOAPmappingRegistry. This registry internally maintains four different Hashtables

  1. Hashtable for Serializers
  2. Hashtable for DeSerializers
  3. Hastable for Java2XML
  4. Hashtable for XML2Java

Hashtable 1 maintains a collection of objects that implement the org.apache.soap.util.Serializer interface and Hashtable 3 maintains a collection of Qnames. The Hashtable 1 and 3 are keyed upon a shared String, which is the encodingStyleURI say "s". If we take an example user-defined data-type UDType and the corresponding Serializer as UDSerializer, then

In Hashtable 1

s-> UDSerializer

In Hashtable 3

s-> UDType.class

The other two Hashtables hold the objects required for Deserialization information as exactly as described above for the Serialization information.

 

To serialize or deserialize a Java object, the registry returns the Qname and the Serializer /DeSerializer object to the caller class. The returned Serializer/Deserializer class is then called to serializer or deserialize the data-type. In the SOAP client that is why we need to exploit a mechanism to define these type mappings in the resgistry and also register to the mapping registry any custom serializers/deserializers that we develop.

An example

Take a deep breath in. You have just been through some very complex material, squeezed in a very short space. If that is not very clear at the moment, don’t worry. Once you look at this example and then go back to that, things might be clearer. Now we will modify our previous example (in part 1) where we will use a Person object as a parameter to our "greetingService" remote SOAP service.We will create a Person java bean. As we have discussed earlier, if we want to use the BeanSerializer class to serialize our Person bean, then the Person class will have to adhere to the java bean specification. More strictly, it has to have a no argument default constructor and a getter and setter method(s) for all its properties.

public class Person extends Object {

    /** Holds value of property name. */
    public String name;
    
    /** Holds value of property age. */
    public int age;
    
    /** Creates new Name */
    public person() {
    }

    /** Getter for property name.
     * @return Value of property name.
 */
    public String getName() {
        return name;
    }
    
    /** Setter for property name.
     * @param name New value of property name.
 */
    public void setName(String name) {
        this.name = name;
    }
    
    /** Getter for property age.
     * @return Value of property age.
 */
    public int getAge() {
        return age;
    }
    
    /** Setter for property age.
     * @param age New value of property age.
 */
    public void setAge(int age) {
        this.age = age;
    }
    
}

We will modify our remote service in such a way that now it accepts the Person object as a parameter.

public class SoapService extends Object {

    /** Creates new SoapService */
    public SoapService() {
    }
    
    /** the remote method accepting a Person object
    */
    public String sayGreeting(Person name)
    {
        return "Hello dear "+name.getName()+" you are really"+name.getAge();
    }
}

All done and now we concentrate on our deployment descriptor. The deployment descriptor now has to explicitly define the <isd:mappings> element. As you see below that the mappings element defines the serializer, and the deserializer to use, and in this case they are the class org.apache.soap.encoding.soapenc.BeanSerializer.

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" 
	id="urn:greetingService">
  <isd:provider type="java" scope="Application" methods="sayGreeting">
    <isd:java class="sam.soap.service.SoapService" static="false"/>
  </isd:provider> 
<isd:mappings>
    <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
             xmlns:x="urn:greetingService" qname="x:sam.soap.client.Person"
             javaType="sam.soap.client.Person"
             java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
             xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
  </isd:mappings>    
</isd:service>
 1 
About | Sitemap | Contact