XML Deserialization using Axis

SOAP web services are supposed to be easy with Axis.  Sometimes, when you’re really lucky it is.  Most of the time though I’m not so lucky.

My problem was this: I had a SOAP web service (probably written in .NET) with literally hundreds of objects.  My goal was to take XML of those objects (just a String input of XML) and turn them into Axis-generated objects so I could properly make web service calls.

My first approach was dead wrong.  I started by trying to parse out the XML myself and call all the associated get/set methods by hand.  I soon realized that writing that much code for hundreds of objects was not an option.

knew there had to be a better way.  As it turns out, there is.

While Axis doesn’t have any “built-in” exposed methods to “turn this XML into an object”, I knew that on some level the code had to exist.  So I started stepping through code and figuring out how Axis did it itself… and as it turns out, what I wanted to do could be accomplished with a few lines of code:

	/**
	 * Reads in the Axis stubbed-out deserializer and turns raw XML into it's associated java object.
	 * @param xmlInput
	 * @param qName
	 * @param javaType
	 * @return Object
	 * @throws Exception
	 */
	public java.lang.Object deserializeObject(String xmlInput,javax.xml.namespace.QName qName, java.lang.Class javaType) throws Exception {
		try {
			// add the SOAP envelope since we we aren't expecting a SOAP object
			String temp = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body>" + xmlInput + "</soapenv:Body></soapenv:Envelope>";
			org.apache.axis.server.AxisServer server = new org.apache.axis.server.AxisServer();
			server.setOption(AxisEngine.PROP_DOMULTIREFS, true);
			MessageContext msgContext = new MessageContext(server);
			java.io.Reader reader = new java.io.StringReader(temp);
			DeserializationContext dser = new DeserializationContext(new org.xml.sax.InputSource(reader),msgContext,org.apache.axis.Message.REQUEST);
			dser.parse();
			SOAPEnvelope env = dser.getEnvelope();
			RPCElement rpcElem = (RPCElement)env.getFirstBody();
			MessageElement struct = rpcElem.getRealElement();
			Object result = struct.getValueAsType(qName,javaType);
			return result;
		} catch (Exception e) {
			throw new Exception("Could not deserialize the XML object:" + e.getMessage());
		}
	}

Going back the other direction is a little easier:

	/**
	 * Turns an object into XML using the Axis-generated serializer
	 * @param object
	 * @param qName
	 * @return String
	 * @throws Exception
	 */
	public String serializeObject(Object object,javax.xml.namespace.QName qName) throws Exception {
		try {
			MessageElement me = new MessageElement(qName, object);
			return me.getAsString();
		} catch (Exception e) {
			throw new Exception("Could not serialize the object:" + e.getMessage());
		}
	}
  1. No comments yet.

  1. No trackbacks yet.