Results 1 to 10 of 10

Thread: Binary data lost on client when using MTOM

  1. #1
    Join Date
    Oct 2010
    Posts
    1

    Question Binary data lost on client when using MTOM

    I am currently evaluating spring-ws 1.5.9 for a webservice, that has to send medium sized binary attachments (pdfs and images).

    I wrote a sample service with an operation 'getPdfDocument', that should return a pdf document of about 160k. I tried to follow the mtom-sample and as far as I can see, I did everything that is suggested.

    As long, as I don´t enable mtom, everything works fine. The binary data gets transmitted inline the message body and the client can access it. But when i enable mtom, the clientside datahandler does not contain any data.

    I´ve enabled message tracing for server and client and the messages seem to be correct in both scenarios. With mtom disabled, the data is transmitted b64-encoded within the message body. With mtom enabled, i can see the binary data as attachment in a separate message part, both for client and server. From message tracing point of view, everything looks fine.

    The problem is, that with mtom enabled, the binary data is not available for my client. In both scenarios i use the following code to write the data to a file. Without mtom the file contains a valid pdf document, but with mtom enabled, the file has a size of 0 bytes. No exceptions or warnings are shown, everything looks fine except the fact, that the data is lost.

    Code:
    FileOutputStream fout = new FileOutputStream(...);
    DataHandler dataHandler = result.getDocumentData();  
    dataHandler.writeTo(fout);
    fout.flush();
    xsd definition for documentData is:

    Code:
    ...
    <xsd:sequence>
      <xsd:element name="documentData" 
          type="xsd:base64Binary"
          xmime:expectedContentTypes="application/octet-stream"/>
    </xsd:sequence>
    ...
    I´m using SaajSoapMessageFactory and jaxb2 marshallers both on server and client and I´m working with the libraries included in the spring-ws distribution. It seems that for some reason attachment data is not correctly bound to the datahandler, but after two days of trying and looking through various forums, I still don´t have a clue whats wrong.

    The fallback strategy would be not using mtom, but given the attachments size and the fact, that our service will have heavy traffic, I´m not happy with that approach. Any help would be highly appreciated.

    Andreas


    Edit: I forgot to mention that the service is running under WAS 7.0.0.5 with parent-last classloading and the following libs attached from the spring-ws distribution: activation-1.1.1, jaxb-api-2.1, jaxb-impl.2.1.5, mail-1.4.1, saaj-api-1.3, saaj-impl-1.3.2, sping-ws-1.5.9-all and the spring-2.5.6 libs.
    Last edited by andino; Oct 20th, 2010 at 10:43 AM. Reason: additional information

  2. #2
    Join Date
    Mar 2010
    Location
    USA
    Posts
    119

    Default pelase help

    hi could uou please let me know what you did further...Am seeing a similar issue here

    Quote Originally Posted by andino View Post
    I am currently evaluating spring-ws 1.5.9 for a webservice, that has to send medium sized binary attachments (pdfs and images).

    I wrote a sample service with an operation 'getPdfDocument', that should return a pdf document of about 160k. I tried to follow the mtom-sample and as far as I can see, I did everything that is suggested.

    As long, as I don´t enable mtom, everything works fine. The binary data gets transmitted inline the message body and the client can access it. But when i enable mtom, the clientside datahandler does not contain any data.

    I´ve enabled message tracing for server and client and the messages seem to be correct in both scenarios. With mtom disabled, the data is transmitted b64-encoded within the message body. With mtom enabled, i can see the binary data as attachment in a separate message part, both for client and server. From message tracing point of view, everything looks fine.

    The problem is, that with mtom enabled, the binary data is not available for my client. In both scenarios i use the following code to write the data to a file. Without mtom the file contains a valid pdf document, but with mtom enabled, the file has a size of 0 bytes. No exceptions or warnings are shown, everything looks fine except the fact, that the data is lost.

    Code:
    FileOutputStream fout = new FileOutputStream(...);
    DataHandler dataHandler = result.getDocumentData();  
    dataHandler.writeTo(fout);
    fout.flush();
    xsd definition for documentData is:

    Code:
    ...
    <xsd:sequence>
      <xsd:element name="documentData" 
          type="xsd:base64Binary"
          xmime:expectedContentTypes="application/octet-stream"/>
    </xsd:sequence>
    ...
    I´m using SaajSoapMessageFactory and jaxb2 marshallers both on server and client and I´m working with the libraries included in the spring-ws distribution. It seems that for some reason attachment data is not correctly bound to the datahandler, but after two days of trying and looking through various forums, I still don´t have a clue whats wrong.

    The fallback strategy would be not using mtom, but given the attachments size and the fact, that our service will have heavy traffic, I´m not happy with that approach. Any help would be highly appreciated.

    Andreas


    Edit: I forgot to mention that the service is running under WAS 7.0.0.5 with parent-last classloading and the following libs attached from the spring-ws distribution: activation-1.1.1, jaxb-api-2.1, jaxb-impl.2.1.5, mail-1.4.1, saaj-api-1.3, saaj-impl-1.3.2, sping-ws-1.5.9-all and the spring-2.5.6 libs.

  3. #3
    Join Date
    Apr 2013
    Posts
    5

    Default MTOM - no xop tag generateed in SOAP message

    Hi,

    I am using the simmilar configuration as yours except for WAS its tomcat.Were you able to find the solution to this problem?

    The issue which i face is that there is no xop tag generated in the SOAP request and the content is send in the message.I think the problem is with JAXB but still I am not sure.

    did anyone get a successful implementation of MTOM in spring 3.0 with JAXB 2?

  4. #4
    Join Date
    Mar 2010
    Location
    USA
    Posts
    119

    Default Did you check on this?

    @Yash2013,

    I did have it successfully configured now.

    Spring 3.0 with tomcat and MTOM really works great.

    But did you check whether the server is sending the data inline with the soap message or as an attachment?
    That might help you with understanding the absence of xop tag in the soap response.

    Thanks
    Priya

    Quote Originally Posted by Yash2013 View Post
    Hi,

    I am using the simmilar configuration as yours except for WAS its tomcat.Were you able to find the solution to this problem?

    The issue which i face is that there is no xop tag generated in the SOAP request and the content is send in the message.I think the problem is with JAXB but still I am not sure.

    did anyone get a successful implementation of MTOM in spring 3.0 with JAXB 2?

  5. #5
    Join Date
    Apr 2013
    Posts
    5

    Default

    Hi,

    Yes,I checked it in SOAPUI the response xml looks like this

    Code:
             <ns3:Object>
                <ns2:Mimetype>application/pdf</ns2:Mimetype>
             <ns2:Content>B3TFSn2EDpPGaYooZ9SWdcbevZUiJA2JLVlUpKoj9JutU73t3E0Y3OTuu2MjlppLYJpZZC+TVB50oGbOsnvcf9yuhZMcsmER5plRBcbZqmuMJUEX+T8XaEo+0+dt33PvvksW3t+Z3fnp842G</ns2:Content>
             </ns3:Object>
    Pasting only the tag which contains the document content.I have used the following settings to ensure MTOM works
    1.In xsd the the Tag for Content is like this

    Code:
    <xs:element name="Content" type="xs:base64Binary"  xmime:expectedContentTypes="application/octet-stream" minOccurs="0"/>

    2.In my config file the settings are --

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:sws="http://www.springframework.org/schema/web-services"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    	http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    	http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
    
    <!-- This is important tag.It enables annotation and hence facilitates endpoint mappings  -->
    <sws:annotation-driven />
        
    <bean id="defaultMethodEndpointAdapter" class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
      <property name="methodArgumentResolvers">
       <list>
        <ref bean="marshallingPayloadMethodProcessor"/>
       </list> 
      </property>
      <property name="methodReturnValueHandlers">
       <list>
        <ref bean="marshallingPayloadMethodProcessor"/>
       </list>
      </property>
     </bean>    
     
     <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
     
     <bean id="marshallingPayloadMethodProcessor" class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
      <constructor-arg ref="jaxbmarshaller"/>
     </bean>
    
    <bean id="soapMessageFactory" class="javax.xml.soap.MessageFactory" factory-method="newInstance" />
    <bean id="saajMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
            <constructor-arg ref="soapMessageFactory" />
    </bean>
        
      <bean id="jaxbmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
      	 <property name="packagesToScan">
                  <list>
                  	<value>com.mydoc.project.schemas</value>
                  	<value>com.mydoc.project.recievedoc</value>
      	    </list>
              </property>
              <property name="mtomEnabled" value="true" />
          </bean>
       
      	 <bean id="recieveDocEndpoint" class="com.mydoc.project.recievedoc.RecieveDocEndPoint">
      	 	<ref bean="recieveDocService"/>
       		<property name="validateInput" value="false"/>
       		<property name="validateOutput" value="false"/>		
       	</bean>
       	
       	<bean id="recieveDocService" class="com.mydoc.project.recievedoc.RecieveDocImpl"/>
       	
       	
       	<bean id="recieveDoc" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
       		<property name="schema">
            	<bean class="org.springframework.xml.xsd.SimpleXsdSchema">
            		<property name="xsd" value="/WEB-INF/classes/services/recievedoc/recievedoc.xsd"/>
            	</bean>	
            	</property>
       		<property name="portTypeName" value="recieveDoc"/>
       		<property name="locationUri" value="http://localhost:8080/recievedoc/webservice"/>				
    	</bean>
       </beans>
    3.In my code ,I am using data handlar to set the content as following
    Code:
    javax.activation.DataHandler dataHandler = new javax.activation.DataHandler(new FileDataSource("test.pdf"));
    System.out.println("Content Type " + dataHandler.getContentType());
    obj.setContent(dataHandler);

    This is as per the specifications,i am not sure where its going wrong either the JAXB is not marshalling it as attachment or there is some other way to set the content in JAXb object.Can you please suggest if your configuration is different.

  6. #6
    Join Date
    Mar 2010
    Location
    USA
    Posts
    119

    Default

    @Yash2013

    You might want to have a look at the following

    I see that the pdf file is coming inline in the SOAP UI response that you have pasted. It does not seem to be an attachment in the response at all. Seems to come as an inline pdf in the SOAP response that is coming. This might be the reason I am thinking that you are not able to get the pdf that is coming through.

    If it comes as inline pdf in the SOAP response, I have literally seen that a SaajFactory with mtom=false really works and gets the inline pdf as required.

    If the pdf comes as attachment, then you might want to have AxiomFactory with mtom=true and this will catch the pdf attachment in SOAP response.

    I have tried both and it works. Can you please let me know what happens? I shall share my config if at all that would help too

    Quote Originally Posted by Yash2013 View Post
    Hi,

    Yes,I checked it in SOAPUI the response xml looks like this

    Code:
             <ns3:Object>
                <ns2:Mimetype>application/pdf</ns2:Mimetype>
             <ns2:Content>B3TFSn2EDpPGaYooZ9SWdcbevZUiJA2JLVlUpKoj9JutU73t3E0Y3OTuu2MjlppLYJpZZC+TVB50oGbOsnvcf9yuhZMcsmER5plRBcbZqmuMJUEX+T8XaEo+0+dt33PvvksW3t+Z3fnp842G</ns2:Content>
             </ns3:Object>
    Pasting only the tag which contains the document content.I have used the following settings to ensure MTOM works
    1.In xsd the the Tag for Content is like this

    Code:
    <xs:element name="Content" type="xs:base64Binary"  xmime:expectedContentTypes="application/octet-stream" minOccurs="0"/>

    2.In my config file the settings are --

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:sws="http://www.springframework.org/schema/web-services"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    	http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    	http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
    
    <!-- This is important tag.It enables annotation and hence facilitates endpoint mappings  -->
    <sws:annotation-driven />
        
    <bean id="defaultMethodEndpointAdapter" class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
      <property name="methodArgumentResolvers">
       <list>
        <ref bean="marshallingPayloadMethodProcessor"/>
       </list> 
      </property>
      <property name="methodReturnValueHandlers">
       <list>
        <ref bean="marshallingPayloadMethodProcessor"/>
       </list>
      </property>
     </bean>    
     
     <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
     
     <bean id="marshallingPayloadMethodProcessor" class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
      <constructor-arg ref="jaxbmarshaller"/>
     </bean>
    
    <bean id="soapMessageFactory" class="javax.xml.soap.MessageFactory" factory-method="newInstance" />
    <bean id="saajMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
            <constructor-arg ref="soapMessageFactory" />
    </bean>
        
      <bean id="jaxbmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
      	 <property name="packagesToScan">
                  <list>
                  	<value>com.mydoc.project.schemas</value>
                  	<value>com.mydoc.project.recievedoc</value>
      	    </list>
              </property>
              <property name="mtomEnabled" value="true" />
          </bean>
       
      	 <bean id="recieveDocEndpoint" class="com.mydoc.project.recievedoc.RecieveDocEndPoint">
      	 	<ref bean="recieveDocService"/>
       		<property name="validateInput" value="false"/>
       		<property name="validateOutput" value="false"/>		
       	</bean>
       	
       	<bean id="recieveDocService" class="com.mydoc.project.recievedoc.RecieveDocImpl"/>
       	
       	
       	<bean id="recieveDoc" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
       		<property name="schema">
            	<bean class="org.springframework.xml.xsd.SimpleXsdSchema">
            		<property name="xsd" value="/WEB-INF/classes/services/recievedoc/recievedoc.xsd"/>
            	</bean>	
            	</property>
       		<property name="portTypeName" value="recieveDoc"/>
       		<property name="locationUri" value="http://localhost:8080/recievedoc/webservice"/>				
    	</bean>
       </beans>
    3.In my code ,I am using data handlar to set the content as following
    Code:
    javax.activation.DataHandler dataHandler = new javax.activation.DataHandler(new FileDataSource("test.pdf"));
    System.out.println("Content Type " + dataHandler.getContentType());
    obj.setContent(dataHandler);

    This is as per the specifications,i am not sure where its going wrong either the JAXB is not marshalling it as attachment or there is some other way to set the content in JAXb object.Can you please suggest if your configuration is different.

  7. #7
    Join Date
    Apr 2013
    Posts
    5

    Default

    Thanks for replying.

    I have tried with SaajFactory option and yes the file comes as attachment since its put explicitly as attachment in code.That is in the message context

    But with this options ,my understanding is that this is not MTOM .This is SOAP with attachment.What i want to achieve is to get the response as MTOM attachment.Also,the response soap message will not have a xop tag but usual content tag with the value set in it.

    I can try with Axiom but i was wondering if that will also result in providing the file as attachment rather than MTOM attachment.

    I am able to get the PDF attachment at client and stream it into the file.Sorry if I posted in wrong thread but my problem is not data loss but MTOM feature not working at all for me.Since its working for you ,may be you can validate if I have done something wrong in this.Thanks once again.

  8. #8
    Join Date
    Mar 2010
    Location
    USA
    Posts
    119

    Default Think you are close.

    @Yash2013,

    Ok. I reread this thread. This is what I understand

    1. with mtom enabled, you had the Saajfactory in your code - Is it? If this is the case, you might surely want to change the facotry to ASIOM as shown below in the code snipper.
    2. Both the server and the client - you are writing and you are using the client to test the server.

    In my case
    1.I was having a SOAP client. The server was sending data as SOAP attachment NOT INLINE ATTACHMENT FILE with MTOM enabled.
    2. Intiially,when I had my client with MTOM = true and a SAAJMessage factory, I was able to see that the client was able to receive the file only when it was an INLINE MESSAGE in the soap response from server. If it was aN MTOM ENABLED ATTCHMENT from the SOAP server, the file at the client reported 0 bytes.
    3. In the above scenario, I went and changed the message factory in the client to AXIOM factory with MTOM =true and this did the magic. The client was able to receive the MTOM ATTACHMENT from server immediately - the following code snippet was at the client then.

    As far as I know, Saaj factory does not support MTOM attachments properly if at all. AxiomFactory is the trick for MTOM enabled attachment.

    Please let me know what you find

    Code:
    <bean id="messageFactory"
    		class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
    		<property name="attachmentCaching" value="true" />
    		<property name="payloadCaching" value="true" />
    		<property name="attachmentCacheThreshold" value="1024" />
    		<property name="attachmentCacheDir" value="directory name" />
    	</bean>
    
    <!-- by default, id="webServiceTemplate will make use of the soap SAAJMessage factory.  -->
    	<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    		<constructor-arg ref="messageFactory" />
    		<property name="marshaller" ref="marshaller" />
    		<property name="unmarshaller" ref="marshaller" />
    		<property name="defaultUri"
    			value="url here" />
    	</bean>
    
    	<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    		<property name="contextPath" value="org.ets.ipackager.webservice" />
    		<property name="mtomEnabled" value="true" />
    
    	</bean>
    
    client handler extends extends WebServiceGatewaySupport
    
    In client handler, I used the following code to catch the attachment (mtom enabled attaachment file - no inline attachment in my case was sent)
     responseObject = getWebServiceTemplate()
                        .marshalSendAndReceive(requestObject)
    Quote Originally Posted by priyavenkat View Post
    @Yash2013

    You might want to have a look at the following

    I see that the pdf file is coming inline in the SOAP UI response that you have pasted. It does not seem to be an attachment in the response at all. Seems to come as an inline pdf in the SOAP response that is coming. This might be the reason I am thinking that you are not able to get the pdf that is coming through.

    If it comes as inline pdf in the SOAP response, I have literally seen that a SaajFactory with mtom=false really works and gets the inline pdf as required.

    If the pdf comes as attachment, then you might want to have AxiomFactory with mtom=true and this will catch the pdf attachment in SOAP response.

    I have tried both and it works. Can you please let me know what happens? I shall share my config if at all that would help too

  9. #9
    Join Date
    Apr 2013
    Posts
    5

    Default

    Thanks for the information.

    1.Yes I do have SaajFactory with MTOM enabled in Server.And I am using the same to send the attachment to the client..So this is SOAP with Attachment.I am able to get the attachment at client ,stream it and save it and open it and all works.

    The response SOAP message contains no xop tag and document is sent as a usual SOAP attachment.And this is my core and only problem. I am not worried about the client implementation and soapui does the job of client for me very well.

    What i want is, to send the attachment from Server to Client (any) as MTOM attachment i.e the response soap message should contain the xop tag with reference to MIME attachment in the SOAP response message.

    I believe the settings you have mentioned here are for client and not for server side settings.Though it might be useful for me later but if you have idea on how to send the MTOM attachment from server to client (Not SOAP attachment) ,please let me know.Thank you.

  10. #10
    Join Date
    Mar 2010
    Location
    USA
    Posts
    119

    Default try this

    ok. Here is the link where they use the SaajMessageFactory itself for MTOM

    http://stackoverflow.com/questions/1...llo-world-test

    http://blog.hpxn.net/2012/06/

    Let me know if it works or not.


    Quote Originally Posted by Yash2013 View Post
    Thanks for the information.

    1.Yes I do have SaajFactory with MTOM enabled in Server.And I am using the same to send the attachment to the client..So this is SOAP with Attachment.I am able to get the attachment at client ,stream it and save it and open it and all works.

    The response SOAP message contains no xop tag and document is sent as a usual SOAP attachment.And this is my core and only problem. I am not worried about the client implementation and soapui does the job of client for me very well.

    What i want is, to send the attachment from Server to Client (any) as MTOM attachment i.e the response soap message should contain the xop tag with reference to MIME attachment in the SOAP response message.

    I believe the settings you have mentioned here are for client and not for server side settings.Though it might be useful for me later but if you have idea on how to send the MTOM attachment from server to client (Not SOAP attachment) ,please let me know.Thank you.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •