5 Replies Latest reply on Aug 2, 2005 4:57 AM by thomas.diesler

    Web Services with XML document or attachment

    ibsscott

      I 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>
      &lt;namespaceURI>http://com.mysite.webservice/WebServiceSession/types</namespaceURI>
      &lt;/package-mapping>
      &lt;package-mapping>
      &lt;package-type>com.mysite.webservice.endpoint&lt;/package-type>
      &lt;namespaceURI>http://com/mysite/webservice/WebServiceSession.wsdl</namespaceURI>
      &lt;/package-mapping>
      &lt;package-mapping>
      &lt;package-type>javax.activation&lt;/package-type>
      &lt;namespaceURI>http://java.sun.com/jax-rpc-ri/internal</namespaceURI>
      &lt;/package-mapping>
      &lt;service-interface-mapping>
      &lt;service-interface>com.mysite.webservice.endpoint.WebServiceSession&lt;/service-interface>
      &lt;wsdl-service-name xmlns:serviceNS="http://com/mysite/webservice/WebServiceSession.wsdl">serviceNS:WebServiceSession&lt;/wsdl-service-name>
      &lt;port-mapping>
      &lt;port-name>WebServiceSessionEndpointPort&lt;/port-name>
      &lt;java-port-name>WebServiceSessionEndpointPort&lt;/java-port-name>
      &lt;/port-mapping>
      &lt;/service-interface-mapping>
      &lt;service-endpoint-interface-mapping>
      &lt;service-endpoint-interface>com.mysite.webservice.endpoint.WebServiceSessionEndpoint&lt;/service-endpoint-interface>
      &lt;wsdl-port-type xmlns:portTypeNS="http://com/mysite/webservice/WebServiceSession.wsdl">portTypeNS:WebServiceSessionEndpoint&lt;/wsdl-port-type>
      &lt;wsdl-binding xmlns:bindingNS="http://com/mysite/webservice/WebServiceSession.wsdl">bindingNS:WebServiceSessionEndpointBinding&lt;/wsdl-binding>
      &lt;service-endpoint-method-mapping>
      &lt;java-method-name>myService&lt;/java-method-name>
      &lt;wsdl-operation>myService&lt;/wsdl-operation>
      &lt;method-param-parts-mapping>
      &lt;param-position>0&lt;/param-position>
      &lt;param-type>javax.activation.DataHandler&lt;/param-type>
      &lt;wsdl-message-mapping>
      &lt;wsdl-message xmlns:wsdlMsgNS="http://com/mysite/webservice/WebServiceSession.wsdl">wsdlMsgNS:WebServiceSessionEndpoint_myService&lt;/wsdl-message>
      &lt;wsdl-message-part-name>DataHandler_1&lt;/wsdl-message-part-name>
      &lt;parameter-mode>IN&lt;/parameter-mode>
      &lt;/wsdl-message-mapping>
      &lt;/method-param-parts-mapping>
      &lt;wsdl-return-value-mapping>
      &lt;method-return-value>javax.activation.DataHandler&lt;/method-return-value>
      &lt;wsdl-message xmlns:wsdlMsgNS="http://com/mysite/webservice/WebServiceSession.wsdl">wsdlMsgNS:WebServiceSessionEndpoint_myServiceResponse&lt;/wsdl-message>
      &lt;wsdl-message-part-name>result&lt;/wsdl-message-part-name>
      &lt;/wsdl-return-value-mapping>
      &lt;/service-endpoint-method-mapping>
      &lt;/service-endpoint-interface-mapping>
      &lt;/java-wsdl-mapping>

      I hope this posts properly. The xml tags cause some text to disappear.