Creating serializers and deserializers

There might be instances where the existing serializers and deserializers provided with the WST are not adequate to expose a class or component through SOAP. In this case, you must create custom serializer and deserializer classes to perform the necessary actions to convert the class to and from XML.

A new serializer and deserializer requires a new Java class that implements the javax.xml.rpc.encoding.Serializer for the serializer and javax.xml.rpc.encoding.DeSerializer for the deserializer.

The following nonbeansample example illustrates various aspects of creating a serializer and deserializer for a user-defined datatype.

Description

The following listing contains these files:

Listing

 /*
*/
package nonbeansample;

import org.apache.axis.encoding.DeserializerImpl;
import org.apache.axis.Constants;
import org.apache.axis.encoding.DeserializationContext;
import org.apache.axis.encoding.Deserializer;
import org.apache.axis.encoding.FieldTarget;
import org.apache.axis.message.SOAPHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import javax.xml.namespace.QName;
import java.util.Hashtable;

/**
 *
 *
 */
public class BookDeserializer extends DeserializerImpl {
		 public static final String NAMEMEMBER = "name";
		 public static final String AUTHORMEMBER = "author";
		 public static final QName myTypeQName = new QName("typeNS", "Book");

		 private Hashtable typesByMemberName = new Hashtable();  

		 public BookDeserializer()
		 {
		 		 typesByMemberName.put(NAMEMEMBER, Constants.XSD_STRING);
		 		 typesByMemberName.put(AUTHORMEMBER, Constants.XSD_STRING);
		 		 value = new Book("","");
		 }

		 /** DESERIALIZER - event handlers
		  */

		 /**
		  * This method is invoked when an element start tag is encountered.
		  * @param namespace is the namespace of the element
		  * @param localName is the name of the element
		  * @param prefix is the element's prefix
		  * @param attributes on the element...used to get the type
		  * @param context is the DeserializationContext
		  */
		 public SOAPHandler onStartChild(String namespace,
		 		 		 		 				 String localName,
		 		 		 		 	 			 String prefix,
		 		 		 		 	 		 	 Attributes attributes,
		 		 		 		 		 		 DeserializationContext context)
		 		 throws SAXException
		 {
		 QName typeQName = (QName)typesByMemberName.get(localName);
		 if (typeQName == null)
	 	 throw new SAXException("Invalid element in Book struct - " + localName);
        
		 		 // These can come in either order.
		 		 Deserializer dSer = context.getDeserializerForType(typeQName);
		 		 try {
		 		 dSer.registerValueTarget(new FieldTarget(value, localName));
		 		 } catch (NoSuchFieldException e) {
		 		 		 throw new SAXException(e);
		 		 }
    
		 		 if (dSer == null)
		 		 		 throw new SAXException("No deserializer for a " + typeQName + "???");
       
		 		 return (SOAPHandler)dSer;
		 }

}
/*
 *
 *
 * package nonbeansample;

import org.apache.axis.encoding.DeserializerFactory;

import org.apache.axis.Constants;
import java.util.Iterator;
import java.util.Vector;

/**
 * *
 *
 */
public class BookDeserFactory implements DeserializerFactory {
		 private Vector mechanisms;

		 public BookDeserFactory() {
		 }
		 public javax.xml.rpc.encoding.Deserializer getDeserializerAs(String mechanismType) {
		 		 return new BookDeserializer();
		 }
		 public Iterator getSupportedMechanismTypes() {
		 		 if (mechanisms == null) {
		 		 		 mechanisms = new Vector();
		 		 		 mechanisms.add(Constants.AXIS_SAX);
		 		 }
		 		 return mechanisms.iterator();
		 }
}
/*
 * 
 *
 * */
package nonbeansample;


/**
 *
 *
 * */
public class Book {
    /** book name */
    public String name;

    /** book author */
    public String author;

    /**
     * Constructor.
     * @param name book name
     * @param author book author
     * @throws IllegalArgumentException name or author is null
     */
    public Book(String name, String author) {
        if (name == null) {
            throw new IllegalArgumentException("Name is null!");
        }

        if (author == null) {
            throw new IllegalArgumentException("Author is null!");
        }

        this.name = name;
        this.author = author;
    }

    /**
     * Test for equality.
     * @param object any object
     * @return true if books are equal
     */
    public boolean equals(Object object) {
        if (!(object instanceof Book)) {
            return false;
        }

        Book secondBook = (Book) object;

        return name.equals(secondBook.name) &&
        author.equals(secondBook.author);
    }
}
/*
 * */
package nonbeansample;

import java.util.Iterator;
import java.util.Vector;
import org.apache.axis.Constants;

import org.apache.axis.encoding.SerializerFactory;

/**
*/
public class BookSerFactory implements SerializerFactory {
		 private Vector mechanisms;

		 public BookSerFactory() {
		 }
		 public javax.xml.rpc.encoding.Serializer getSerializerAs(String mechanismType) {
		 		 return new BookSerializer();
		 }
		 public Iterator getSupportedMechanismTypes() {
		 		 if (mechanisms == null) {
		 		 		 mechanisms = new Vector();
		 		 		 mechanisms.add(Constants.AXIS_SAX);
		 		 }
		 		 return mechanisms.iterator();
		 }
}
*/
package nonbeansample;

import java.io.IOException;

import javax.xml.namespace.QName;

import org.apache.axis.encoding.SerializationContext;
import org.apache.axis.encoding.Serializer;
import org.apache.axis.wsdl.fromJava.Types;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.apache.axis.Constants;

/**
*/
public class BookSerializer implements Serializer {
		 public static final String NAMEMEMBER = "name";
		 public static final String AUTHORMEMBER = "author";
		 public static final QName myTypeQName = new QName("nonBeanTypes", "Book");

		 /** SERIALIZER 
		  */
		 /**
		  * Serialize an element named name, with the indicated attributes
		  * and value.
		  * @param name is the element name
		  * @param attributes are the attributes...serialize is free to add more.
		  * @param value is the value
		  * @param context is the SerializationContext
		  */
		 public void serialize(
		 		 QName name,
		 		 Attributes attributes,
		 		 Object value,
		 		 SerializationContext context)
		 		 throws IOException {
		 		 if (!(value instanceof Book))
		 		 		 throw new IOException(
		 		 		 		 "Can't serialize a "
		 		 		 		 		 + value.getClass().getName()
		 		 		 		 		 + " with a BookSerializer.");
		 		 Book data = (Book) value;

		 		 context.startElement(name, attributes);
		 		 context.serialize(new QName("", NAMEMEMBER), null, data.name);
		 		 context.serialize(new QName("", AUTHORMEMBER), null, data.author);
		 		 context.endElement();
		 }
		 public String getMechanismType() {
		 		 return Constants.AXIS_SAX;
		 }

		 /* (non-Javadoc)
		  * @see org.apache.axis.encoding.Serializer#writeSchema(java.lang.Class, org.apache.axis.wsdl.fromJava.Types)
		  */
		 public Element writeSchema(Class arg0, Types types) throws Exception {
		 		 //  Auto-generated method stub
		 		 Element complexType = types.createElement("complexType");
		 		 types.writeSchemaElement(myTypeQName, complexType);
		 		 complexType.setAttribute("name", myTypeQName.getLocalPart());
		 		 Element seq = types.createElement("sequence");
		 		 complexType.appendChild(seq);

		 		 Element element = types.createElement("element");
		 		 element.setAttribute("name", "name");
		 		 element.setAttribute("type", "xsd:string");
		 		 seq.appendChild(element);
		 		 Element element2 = types.createElement("element");
		 		 element2.setAttribute("name", "author");
		 		 element2.setAttribute("type", "xsd:string");
		 		 seq.appendChild(element2);

		 		 return complexType;
		 }
}