Yes, I am trying to do object serialization/deserialization outside the
SOAP environment, but find the objects created by the Apache Axis
toolkit too convenient to give up. So, I was looking for ways to switch
between the XML request/responses and the appropriate objects. I think
I've pretty well mastered that.
Ralph
import gov.loc.www.zing.srw.ScanRequestType;
import gov.loc.www.zing.srw.ScanResponseType;
import gov.loc.www.zing.srw.SearchRetrieveRequestType;
import gov.loc.www.zing.srw.SearchRetrieveResponseType;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.namespace.QName;
import org.apache.axis.MessageContext;
import org.apache.axis.encoding.DeserializationContext;
import org.apache.axis.encoding.SerializationContext;
import org.apache.axis.encoding.Serializer;
import org.apache.axis.message.RPCElement;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.server.AxisServer;
import org.xml.sax.InputSource;
public static String objToXml(Object obj)
throws IllegalArgumentException, IOException {
QName qn;
Serializer s;
if(obj instanceof SearchRetrieveRequestType) {
qn=new QName("http://www.loc.gov/zing/srw/",
"searchRetrieveRequest");
s=((SearchRetrieveRequestType)obj).getSerializer(
null, obj.getClass(), qn);
}
else if(obj instanceof SearchRetrieveResponseType) {
qn=new QName("http://www.loc.gov/zing/srw/",
"searchRetrieveResponse");
s=((SearchRetrieveResponseType)obj).getSerializer(
null, obj.getClass(), qn);
}
else if(obj instanceof ScanRequestType) {
qn=new QName("http://www.loc.gov/zing/srw/", "scanRequest");
s=((ScanRequestType)obj).getSerializer(
null, obj.getClass(), qn);
}
else if(obj instanceof ScanResponseType) {
qn=new QName("http://www.loc.gov/zing/srw/",
"scanResponse");
s=((ScanResponseType)obj).getSerializer(
null, obj.getClass(), qn);
}
else throw new IllegalArgumentException(
"Unrecognized object: "+obj.getClass().getName());
StringWriter xmlWriter=new StringWriter();
s.serialize(qn, null, obj, new SerializationContext(xmlWriter));
return xmlWriter.toString();
}
static String EnvelopeStart="<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>";
static String EnvelopeEnd="</soapenv:Body></soapenv:Envelope>";
public static Object xmlToObj(String xml) throws Exception {
Object obj;
String leader, soapMessage;
leader=xml.substring(0, 20);
if(leader.toLowerCase().startsWith("<?")) {
// contains processing instruction. Strip that off
int i=xml.indexOf("Envelope");
if(i<0)
throw new IllegalArgumentException("XML starts with
processing instruction but contains no SOAP Envelope");
while(i>0 && xml.charAt(i)!='<')
i--;
if(i==0)
throw new IllegalArgumentException("XML starts with
processing instruction but contains no SOAP Envelope element");
soapMessage=xml.substring(i);
}
else if(leader.contains("Envelope")) // use it as it is
soapMessage=xml;
else // add the soap envelope wrapper
soapMessage=EnvelopeStart+xml+EnvelopeEnd;
DeserializationContext dser = new DeserializationContext(
new InputSource(new StringReader(soapMessage)),
new MessageContext(new AxisServer()),
org.apache.axis.Message.RESPONSE);
dser.parse();
SOAPEnvelope env = dser.getEnvelope();
RPCElement rpcElem = (RPCElement)env.getFirstBody();
String objectType=rpcElem.getLocalName();
if(objectType.equals("searchRetrieveRequest"))
obj=rpcElem.getObjectValue(SearchRetrieveRequestType.class);
else if(objectType.equals("searchRetrieveResponse"))
obj=rpcElem.getObjectValue(SearchRetrieveResponseType.class);
else if(objectType.equals("scanRequest"))
obj=rpcElem.getObjectValue(ScanRequestType.class);
else if(objectType.equals("scanResponse"))
obj=rpcElem.getObjectValue(ScanResponseType.class);
else
throw new IllegalArgumentException("Unrecognized XML object:
"+objectType);
return obj;
}
|