I've got a situation where I need to write a custom serializer for classes that are able to give the XML representations of themselves via toString(). I've messed around with writing a custom serializer in various ways, following the examples of BeanSerializer, DocumentSerializer, etc.. just trying thing out and can't seem to come up with any encouraging leads.

Here's my current serializer factory:


package grega.encoding.ser;

import javax.xml.namespace.QName;
import javax.xml.rpc.JAXRPCException;

import org.apache.axis.encoding.Serializer;
import org.apache.axis.encoding.ser.BaseSerializerFactory;

public class MySerializerFactory extends BaseSerializerFactory {

    public MySerializerFactory(Class javaType, QName xmlType) {
        super(MySerializer.class, xmlType, javaType);
    }

    public javax.xml.rpc.encoding.Serializer getSerializerAs(String mechanismType)
            throws JAXRPCException {
        return (Serializer) super.getSerializerAs(mechanismType);
    }

    /**
     * Optimize construction of a BeanSerializer by caching the type and property
     * descriptors.
     */
    protected Serializer getGeneralPurpose(String mechanismType) {
        return new MySerializer();
    }
}

and here's my current serializer:

package grega.encoding.ser;

import java.io.IOException;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

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

import grega.SaxContainer;


public class MySerializer implements Serializer {

    public void serialize(QName qName, Attributes attribs, Object value,
            SerializationContext ctx) throws IOException {
        if (value instanceof SaxContainer) {
            ctx.startElement(qName, attribs);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            try {
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse(value.toString());
                ctx.writeDOMElement(doc.getDocumentElement());
                ctx.endElement();
            } catch (SAXException e) {
                throw new IOException(e.getMessage());
            } catch (ParserConfigurationException e) {
                throw new IOException(e.getMessage());
            }
        } else {
            throw new IOException("value is a " + value.getClass() + ", not a SaxContainer");
        }

    }

    public Element writeSchema(Class clazz, Types types) throws Exception {
        return null;
    }

    public String getMechanismType() {
        return Constants.AXIS_SAX;
    }
}


Now what's confusing to me is that if I have a server-config.wsdd containing this:

<typeMapping qname="typens:Country"
        type="java:grega.CountryXml"
        serializer="grega.encoding.ser.MySerializerFactory"
        deserializer="grega.ser.MyDeserializerFactory"
    />

in the MySerializer.serialize method, the QName argument has a value of "multiRef". I don't want to serialize to a multiref element, I want to serialize directly into the place where the type is used in the SOAP message, right? So I figure that Axis is trying to do some kind of multi-ref SOAP encoding, and I remember reading somewhere (this whole Axis thing is kind of a haze), about using encodingStyle="" on the typemapping when using document or wrapped style services, which I am, so I changed it to:

<typeMapping qname="typens:Country"
        type="java:grega.CountryXml"
        serializer="grega.encoding.ser.MySerializerFactory"
        deserializer="grega.ser.MyDeserializerFactory"
        encodingStyle=""
    />

but then I get the following AxisFault at serialization time:

AxisFault
 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
 faultSubcode:
 faultString: java.io.IOException: No serializer found for class grega.CountryXml in registry [EMAIL PROTECTED]


so apparently setting encodingStyle="" causes my typeMapping to not register MySerializer as valid for the type I'm configuring. Why?

Any pointers on how to get the serializer to work would be greatly appreciated. There's so little documentation on how custom serialization works in Axis.

Thanks,
Greg Adams

Reply via email to