Results 1 to 10 of 10

Thread: Binary data lost on client when using MTOM

Hybrid View

  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.

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
  •