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 © 2003. Sybase Inc. All rights reserved. |
|
|