Web Services with XML document or attachment
ibsscott Jul 28, 2005 3:29 AMI have read through every Wiki there is about Web Services but cannot find a solution that works. I am trying to pass an XML document to my web service. I can do it if the service is expecting a simple String. I am trying to marshal an Object into an object the web service supports. I would like to pass an org.w3c.dom.Element, or javax.xml.transform.Source, or javax.activation.DataHandler, or anything but a String. For the Element type, I tried to use the document literal model. WsCompile ended up creating a new Element class and made it part of my package such as mypackage.Element instead of letting me use org.w3c.dom.Element. It converted my SEI data types to the newly generated myPackage.Element class. I thought maybe the generated classes would act as a wrapper for org.w3c.dom.Element but I saw no reference to that and could not figure it out. I tried building the wsdl by hand matching the example online, but I had no success trying to get the web service to accept org.w3c.dom.Element. I think it didn't like xsd:anyType.
So I gave up on that and thought I would try attachments instead. I tried making my SEI use javax.xml.transform.Source as parameters since the documentation seems to say this is a valid web service type. This was a nightmare. I couldn't pass it a SAXSource or a DOMSource as they are not supported and finally had to settle for a StreamSource. That gave me:
14:43:17,484 ERROR [RPCInvocation] java.lang.ClassCastException: org.jboss.axis.
message.SOAPBodyElementAxisImpl
java.lang.ClassCastException: org.jboss.axis.message.SOAPBodyElementAxisImpl
at org.jboss.axis.encoding.ser.JAFDataHandlerDeserializer.startElement(J
AFDataHandlerDeserializer.java:121)
at org.jboss.axis.encoding.ser.SourceDataHandlerDeserializer.startElemen
t(SourceDataHandlerDeserializer.java:82)
at org.jboss.axis.encoding.DeserializationContextImpl.startElement(Deser
ializationContextImpl.java:1182)
etc..
Then I decided to give the DataHandler a try. I downloaded the example from http://wiki.jboss.org:80/wiki/attach?page=JBossWSAttachStepByStep%2Fwsattachment.zip . It always seems I am missing a piece somewhere and in this case the jaxrpc-mapping.xml file was not included. Once again, I built my SEI, and ran wscompile to get my jaxrpc-mapping.xml and my wsdl. On startup, I receive this message:
...
01:33:33,265 WARN [JavaWsdlMapping] Cannot find jaxrpc-mapping for type: {http:
//java.sun.com/jax-rpc-ri/internal}datahandler
01:33:33,356 WARN [TypeMappingDescription] Class not found: javax.activation.da
tahandler
01:33:33,366 INFO [AxisService] WSDD published to: C:\jboss-4.0.2\server\default......
Not sure if it means anything that datahandler is lower case... My jaxrpc-mapping.xml is in my META-INF directory which I know is correct since I struggled with this for a while. When I execute a client against this deployment, I get:
on the Server:
-------------------
01:55:09,990 ERROR [RPCInvocation] org.xml.sax.SAXException: Deserializing param
eter 'DataHandler_1': could not find deserializer for type {http://java.sun.com
/jax-rpc-ri/internal}datahandler
org.xml.sax.SAXException: Deserializing parameter 'DataHandler_1': could not fi
nd deserializer for type {http://java.sun.com/jax-rpc-ri/internal}datahandler
at org.jboss.axis.message.RPCHandler.onStartChild(RPCHandler.java:326)
at org.jboss.axis.encoding.DeserializationContextImpl.startElement(Deser
ializationContextImpl.java:1168)
at org.jboss.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.jav
a:244)
On the Client:
-------------------------
java.io.IOException: "text/xml" DataContentHandler requires String object, was given object of type class javax.xml.transform.stream.StreamSource
at com.sun.mail.handlers.text_plain.writeTo(text_plain.java:103)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:839)
at javax.activation.DataHandler.writeTo(DataHandler.java:295)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1147)
I am passing a StreamSource to the DataHandler with MIME type text/xml
DataHandler dataHandler = new DataHandler(source, "text/xml");
dataHandler = endpoint.myService(dataHandler);
I get the "cannot find deserializer" message quite often and I can't take it any more. I need help. I haven't slept in days trying to get this to work. What am I missing???
Latest wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="WebServiceSession" targetNamespace="http://com/mysite/webservice/WebServiceSession.wsdl" xmlns:tns="http://com/mysite/webservice/WebServiceSession.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns2="http://java.sun.com/jax-rpc-ri/internal" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<schema targetNamespace="http://java.sun.com/jax-rpc-ri/internal" xmlns:tns="http://java.sun.com/jax-rpc-ri/internal" xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<simpleType name="datahandler">
<restriction base="base64Binary"/></simpleType></schema></types>
<message name="WebServiceSessionEndpoint_myService">
<part name="DataHandler_1" type="ns2:datahandler"/></message>
<message name="WebServiceSessionEndpoint_myServiceResponse">
<part name="result" type="ns2:datahandler"/></message>
<portType name="WebServiceSessionEndpoint">
<operation name="myService" parameterOrder="DataHandler_1">
<input message="tns:WebServiceSessionEndpoint_myService"/>
<output message="tns:WebServiceSessionEndpoint_myServiceResponse"/></operation></portType>
<binding name="WebServiceSessionEndpointBinding" type="tns:WebServiceSessionEndpoint">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<operation name="myService">
<soap:operation soapAction=""/>
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://com/mysite/webservice/WebServiceSession.wsdl"/></input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://com/mysite/webservice/WebServiceSession.wsdl"/></output></operation></binding>
<service name="WebServiceSession">
<port name="WebServiceSessionEndpointPort" binding="tns:WebServiceSessionEndpointBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/></port></service></definitions>
latest mapping:
<?xml version="1.0" encoding="UTF-8"?>
<java-wsdl-mapping xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_jaxrpc_mapping_1_1.xsd">
<package-mapping>
<package-type>com.mysite.webservice.endpoint</package-type>
<namespaceURI>http://com.mysite.webservice/WebServiceSession/types</namespaceURI>
</package-mapping>
<package-mapping>
<package-type>com.mysite.webservice.endpoint</package-type>
<namespaceURI>http://com/mysite/webservice/WebServiceSession.wsdl</namespaceURI>
</package-mapping>
<package-mapping>
<package-type>javax.activation</package-type>
<namespaceURI>http://java.sun.com/jax-rpc-ri/internal</namespaceURI>
</package-mapping>
<service-interface-mapping>
<service-interface>com.mysite.webservice.endpoint.WebServiceSession</service-interface>
<wsdl-service-name xmlns:serviceNS="http://com/mysite/webservice/WebServiceSession.wsdl">serviceNS:WebServiceSession</wsdl-service-name>
<port-mapping>
<port-name>WebServiceSessionEndpointPort</port-name>
<java-port-name>WebServiceSessionEndpointPort</java-port-name>
</port-mapping>
</service-interface-mapping>
<service-endpoint-interface-mapping>
<service-endpoint-interface>com.mysite.webservice.endpoint.WebServiceSessionEndpoint</service-endpoint-interface>
<wsdl-port-type xmlns:portTypeNS="http://com/mysite/webservice/WebServiceSession.wsdl">portTypeNS:WebServiceSessionEndpoint</wsdl-port-type>
<wsdl-binding xmlns:bindingNS="http://com/mysite/webservice/WebServiceSession.wsdl">bindingNS:WebServiceSessionEndpointBinding</wsdl-binding>
<service-endpoint-method-mapping>
<java-method-name>myService</java-method-name>
<wsdl-operation>myService</wsdl-operation>
<method-param-parts-mapping>
<param-position>0</param-position>
<param-type>javax.activation.DataHandler</param-type>
<wsdl-message-mapping>
<wsdl-message xmlns:wsdlMsgNS="http://com/mysite/webservice/WebServiceSession.wsdl">wsdlMsgNS:WebServiceSessionEndpoint_myService</wsdl-message>
<wsdl-message-part-name>DataHandler_1</wsdl-message-part-name>
<parameter-mode>IN</parameter-mode>
</wsdl-message-mapping>
</method-param-parts-mapping>
<wsdl-return-value-mapping>
<method-return-value>javax.activation.DataHandler</method-return-value>
<wsdl-message xmlns:wsdlMsgNS="http://com/mysite/webservice/WebServiceSession.wsdl">wsdlMsgNS:WebServiceSessionEndpoint_myServiceResponse</wsdl-message>
<wsdl-message-part-name>result</wsdl-message-part-name>
</wsdl-return-value-mapping>
</service-endpoint-method-mapping>
</service-endpoint-interface-mapping>
</java-wsdl-mapping>
I hope this posts properly. The xml tags cause some text to disappear.