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.
The following listing contains these files:
Book.java – the type class, which needs a custom serializer/deserializer since it’s not a valid Java Bean or a type for which WST provides built in mappings (like IDL types).
BookSerFactory – the factory used to get the serializer. Currently WST supports only SAX serializer/deserializer, but factory is the interface to get XML parser specific serializers/deserializers.
BookDeserFactory – the factory used to get the deserializer.
BookSerializer – contains the logic to convert Java type to XML, also contains write schema which can be implemented. Write schema is used during WSDL generation. This class implements javax.xml.rpc.encoding.Serializer.
BookDeserializer – contains the logic to
convert XML to java type. This class is an extension of org.apache.axis.encoding.DeserializerImpl
and
provides the base functionality. The deserializerImpl
class
implements the javax.xml.rpc.encoding.Deserializer
.
You can also write all the deserialization logic on your own.
/* */ 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; } }
Copyright © 2005. Sybase Inc. All rights reserved. |
![]() |