11 Replies Latest reply on Nov 20, 2006 11:38 AM by Romeu Figueira

    Problem with SAAJ Client for Webservice that receives attach

    Romeu Figueira Newbie

      Hi there, I've implemented a webservice (JSR-109) that receives two parameters and one attachment. It's working fine, testing with soapui 1.6 beta2 showed that my service could receive and store attachments without a problem.

      Now I wanted to create a SAAJ client to make contact with such webservice. I have previous experience developing clients without the attachment part, but in this one I'm having problems.

      I've based my client on this one http://labs.jboss.com/portal/jbossws/user-guide/en/html/attachments.html
      but when interacting with the webservice, I keep on getting this message:

      <env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
       <env:Header/>
       <env:Body>
       <env:Fault xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
       <faultcode>env:Client</faultcode>
       <faultstring>multipart/related type specified a root type other than the one that was found.</faultstring>
       </env:Fault>
       </env:Body>
      </env:Envelope>


      This is my request message via soapUI
       ------=_Part_1_20574010.1162549201841
       Content-Type: text/xml; charset=UTF-8
       Content-Transfer-Encoding: 8bit
       Content-ID: <rootpart@soapui.org>
      
       <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:.mediation">
       <soapenv:Header/>
       <soapenv:Body>
       <urn:depositAttach>
       <id_lote>5</id_lote>
       <file_name>text</file_name>
       </urn:depositAttach>
       </soapenv:Body>
       </soapenv:Envelope>
       ------=_Part_1_20574010.1162549201841
       Content-Type: text/plain; charset=us-ascii
       Content-Transfer-Encoding: 7bit
       Content-ID: <mimepart=1788743063992@soapui.org>
      
       Text message here
       ------=_Part_1_20574010.1162549201841--
      


      And this is my message via my SAAJ client
      ------=_Part_0_12285029.1162549416820
      Content-Type: text/xml; charset=utf-8
      
      <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:mediation">
       <SOAP-ENV:Header/>
       <SOAP-ENV:Body>
       <urn:depositAttach>
       <id_lote>1</id_lote>
       <file_name>text</file_name>
       </urn:depositAttach>
       </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>
      ------=_Part_0_12285029.1162549416820
      Content-Type: multipart/mixed;
       boundary="----=_Part_0_28470003.1162549416710"
      Content-ID: <mimepart=1876756521231@example.com>
      
      ------=_Part_0_28470003.1162549416710
      Content-Type: text/plain
      
      Text message here
      ------=_Part_0_28470003.1162549416710--
      
      ------=_Part_0_12285029.1162549416820--
      


      Additionaly, here is the header of the SOAP transmission from soapUI
       SOAPAction: ""
       Content-Type: multipart/related; type="text/xml";
       start="<rootpart@soapui.org>";
       boundary="----=_Part_1_20574010.1162549201841
       MIME-Version: 1.0
       User-Agent: Jakarta Commons-HttpClient/3.0.1
       Host: localhost:8080
       Content-Length: 697
      


      Now, here's my problem, I know that the messages are correct, as you can also see, but there must be something wrong with my definiton of attachment. I cannot reproduce the part highlighted in the soapui message, and think that is where my problem lays. Somewere in server process, when the message goes through my client, it can't split the message into two, the Body Part and the Attachment part, and complains when it finds a "text/plain" instead of "text/xml".

      Can you help me here?

        • 1. Re: Problem with SAAJ Client for Webservice that receives at
          Romeu Figueira Newbie

          Forgot to add:

          Running JBoss AS 4.0.5 with JBossWS 1.0.3

          • 3. Re: Problem with SAAJ Client for Webservice that receives at
            Romeu Figueira Newbie

            Ok, further info.

            This is from a very similar webservice, only difference in this one is that it deals with JPEGs.

            These are TCPmon captures.

            My Client (attachment output ommited):

            POST /MediationAttachPic HTTP/1.1
            Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
            Content-Type: multipart/related;
            type="text/xml";
            boundary="----=_Part_1_17933220.1162911613951"
            Content-Length: 4228
            SOAPAction: ""
            Cache-Control: no-cache
            Pragma: no-cache
            User-Agent: Java/1.5.0_08
            Host: 127.0.0.1:8081
            Connection: keep-alive
            
            ------=_Part_1_17933220.1162911613951
            Content-Type: text/xml; charset=utf-8
            
            <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:com.mediation">
             <SOAP-ENV:Body>
             <urn:depositAttach>
             <id_lote>1</id_lote>
             <file_name>xml-pic</file_name>
             </urn:depositAttach>
             </SOAP-ENV:Body></SOAP-ENV:Envelope>
             ------=_Part_1_17933220.1162911613951
             Content-Type: image/jpeg
             Content-ID: <imgpart=5e62851c:10ec2ef030e:-8000@example.com>


            SOAPui (attachment output ommited):
            POST /MediationAttachPic HTTP/1.1
            SOAPAction: ""
            Content-Type: multipart/related;
            type="text/xml";
            start="<rootpart@soapui.org>";
            boundary="----=_Part_0_26490427.1162911728786"
            MIME-Version: 1.0
            User-Agent: Jakarta Commons-HttpClient/3.0.1
            Host: 127.0.0.1:8081
            Content-Length: 4381
            
            
            ------=_Part_0_26490427.1162911728786
            Content-Type: text/xml; charset=UTF-8
            Content-Transfer-Encoding: 8bit
            Content-ID: <rootpart@soapui.org>
             <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:com.mediation">
             <soapenv:Header/>
             <soapenv:Body>
             <urn:depositAttach>
             <id_lote>2</id_lote>
             <file_name>xml_pic</file_name>
             </urn:depositAttach>
             </soapenv:Body>
             </soapenv:Envelope>
             ------=_Part_0_26490427.1162911728786
             Content-Type: image/jpeg
             Content-Transfer-Encoding: binary
             Content-ID:
             <imgpart=15912942847484@soapui.org>


            The main difference to me is this line, which I believe is the one causing errors:
            start="<rootpart@soapui.org>";


            How can I define this in my client?

            SAAJ_ATTACH_CLIENT
            public class SAAJ_Attach_Client
            {
             public static final String NAMESPACE_URI = "com.mediation";
             public static final String PREFIX = "urn";
             public static final String METHOD = "depositAttach";
             public static final File attach = new File("xml-pic.jpg");
             public static final String WS_URI = "http://localhost:8081/MediationAttachPic";
            
             public static void main(String[] args)
             {
            
             try
             {
             MessageFactory msgFactory = MessageFactory.newInstance();
             SOAPMessage msg = msgFactory.createMessage();
             SOAPPart soapPart = msg.getSOAPPart();
             SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
            
             soapEnvelope.addNamespaceDeclaration(PREFIX,PREFIX+":"+NAMESPACE_URI);
            
             // for this tutorial web service, we don't have any headers,
             // so detach the one we get for "free":
             SOAPHeader soapHeader = soapEnvelope.getHeader();
             soapHeader.detachNode();
            
             // to the body, add the document we want to send to the
             // profile update web service:
             SOAPBody body = msg.getSOAPBody();
             SOAPFactory soapFactory = SOAPFactory.newInstance();
             Name bodyName = soapFactory.createName(METHOD,PREFIX, "");
             SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
            
             // add the "profileID" element:
             Name profileIDParamName = soapFactory.createName("id_lote");
             SOAPElement profileID = bodyElement.addChildElement(profileIDParamName);
             profileID.addTextNode("1");
            
             // add the "profilePhotoRef" reference to the photo we will attach:
             Name profilePhotoRefParamName = soapFactory.createName("file_name");
             SOAPElement profilePhotoRef = bodyElement.addChildElement(profilePhotoRefParamName);
            
             profilePhotoRef.addTextNode("xml-pic");
            
             // get the image file and attach it:
             AttachmentPart binaryAttachPart = null;
            
             FileDataSource binaryFds = new FileDataSource(attach);
             DataHandler binaryFileHandler = new DataHandler(binaryFds);
             binaryAttachPart = msg.createAttachmentPart(binaryFileHandler);
             binaryAttachPart.setContentType("image/jpeg");
            
             binaryAttachPart.setContentId("<imgpart="+ (new java.rmi.server.UID()).toString() + "@example.com>");
             msg.addAttachmentPart(binaryAttachPart);
            
             if (msg.saveRequired())
             {
             msg.saveChanges();
             }
            
             // echo the document first:
             System.out.println("\nAbout to send the following SOAPMessage:\n");
             msg.writeTo(System.out);
             System.out.println("\nto endpoint URL " + WS_URI + "\n");
            
             // ...then send it, and echo the response:
             SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
             SOAPConnection soapConn = soapConnFactory.createConnection();
             SOAPMessage responseMsg = soapConn.call(msg, WS_URI);
             System.out.println("\nGot the following SOAPMessage in response:\n");
             responseMsg.writeTo(System.out);
            
             // in real life, declare outside of block and close in finally
             soapConn.close();
             }
             catch (IOException ioe)
             {
             System.err.println("IOException writing SOAPMessage: '" + ioe.getMessage() + "'");
             }
             catch (SOAPException se)
             {
             System.err.println("SOAPException: '" + se.getMessage() + "'");
             System.err.println(" Cause: '" + se.getCause().getClass().getName() + "': " + se.getCause().getMessage());
             }
            
             }
            
             public SAAJ_Attach_Client()
             {
             }
            }


            • 5. Re: Problem with SAAJ Client for Webservice that receives at
              Romeu Figueira Newbie

               

              "heiko.braun@jboss.com" wrote:
              Sorry, i cannot dig into your problem in great detail right now, but did you checkout the following:

              http://labs.jboss.com/portal/jbossws/user-guide/en/html/attachments.html
              http://labs.jboss.com/portal/jbossws/user-guide/en/html/mtom-xop.html


              Hi Heiko, I've seen those documents before. My service and client are even partially based on the samples provided by jbossws13 (all the way to wsdl and jax-mapping). I'm not using MTOM at this moment.

              I'm starting to consider that I may have some JAR problems with my libraries but can't confirm it.

              It's just plain weird that I can do a upload with SoapUI and can't with any of my SAAJ clients.

              • 6. Re: Problem with SAAJ Client for Webservice that receives at
                Romeu Figueira Newbie

                Current JARs that I'm using to call this client:

                activation.jar
                mail.jar
                saaj-api.jar
                saaj-impl.jar
                xercesImpl.jar
                


                • 7. Re: Problem with SAAJ Client for Webservice that receives at
                  Romeu Figueira Newbie

                  Ok, after all this time I've did the following test:

                  Build and deployed jbossws-samples-swa.war from jbossws/samples to my JBoss Server.

                  Then I used AttachmentSAAJTestCase.java, again from jbossws/samples removing the Junit part, and it FAILED again with the same message:

                  multipart/related type specified a root type other than the one that was found.


                  I'm feeling that something is wrong here, but I cannot accert to what it is? Is it my SAAJ libraries, is it Jboss SAAJ implementation?

                  Heikko, Diesler, could you please share some insight into this? It would be much appreciated.



                  • 8. Re: Problem with SAAJ Client for Webservice that receives at
                    Romeu Figueira Newbie

                    Finally managed to fix this.

                    After spending the last hours dealing with JBossWS source-code, I've managed to do a small change that enabled my message to be correctly interpreted.

                    If you remmember I wasn't specifining in my mimeheaders, where my rootpart was. The problem was that the class MultipartRelatedDecoder wasn't computing a valid MIME boundary, the one I was getting was messy, making the code skip my text/xml part into the attachment part, thus giving out those errors.

                    After interpreting both InputStreams, the main difference from any of my standalone clients and the SOAPUi or the Junit test reports was that without a start part, my InputStream started in the first line, while the other started a line below.

                    So, in order to enable a detection of a valid boundary, I had to do the following change to MultipartRelatedDecoder.java:

                    old:

                    try
                    {
                     boundary = ("\r\n--" + boundaryParameter).getBytes("US-ASCII");
                    }
                    



                    new:
                    try
                    {
                     if(start==null)
                     boundary = ("--" + boundaryParameter).getBytes("US-ASCII");
                     else
                     boundary = ("\r\n--" + boundaryParameter).getBytes("US-ASCII");
                    }
                    


                    This way, both systems work. IMO the old code is a little bit too hard-coded in this aspect, giving a weird error when the simple difference between files was a linefeed (which I didn't program in my code, it was introduced through the communication layer).

                    Perhaps this aspect could be improved.

                    Thanks for making this project opensource, if not it would have been almost impossible to work this out.

                    Regards,

                    Romeu

                    • 9. Re: Problem with SAAJ Client for Webservice that receives at
                      Thomas Diesler Master

                      Could you please create a jira issue and attach a patch against the 1.0.4 testsuite that allows us to reproduce this issue.

                      cheers

                      • 11. Re: Problem with SAAJ Client for Webservice that receives at
                        Romeu Figueira Newbie

                         

                        "thomas.diesler@jboss.com" wrote:
                        Could you please create a jira issue and attach a patch against the 1.0.4 testsuite that allows us to reproduce this issue.

                        cheers


                        Issue created at http://jira.jboss.org/jira/browse/JBWS-1393

                        Small test client attached.

                        Solution provided (may not be the best solution, should be more generic)