10 Replies Latest reply on Feb 22, 2010 2:39 PM by BKBK

    Capturing XML to be sent to a Web Service

    Al Baker

      I need to generate the XML to be sent to a cfc remote function (web service)-- but not actually send the XML!

       

      It is easy to use <cfinvoke ...> pointing to the WSDL to actually send the XML, but I can't do that.

       

      What I need to do is capture the XML that would be sent to the service and store it in a database record in an ntext field along with the URL of the web service.

       

      Then a second process will do the actual transmission of the XML to the URL.

       

      (The reason is that the transmission MUST happen and I want to isolate the user of the service from the generic asynchronous process that will do the actual transmission repeatedly until it succeeds.  The user stores the web service URL and data in a table which a second asynchronous process then attempts to deliver until successful.)

       

      So, how do I use <cfinvoke ...><cfinvokeargument...>...</cfinvoke> (or some other process) to grab the XML that would be sent to the web service without actually sending it?

       

      I also don't want to simply pass all the information to the asynchronous process and let it do the <cfinvoke>. This adds processing to store all the information (and there is a lot of it) into the table and then collect the information from the table and build the XML for each attempt.  This also adds intelligence to the generic asynchronous process it doesn't need to possess.

       

      I suspect there is a simple solution I'm not seeing because this is clearly something commonly needed.

        • 1. Re: Capturing XML to be sent to a Web Service
          TiGGi Level 1

          Tell me if I got this right, you want user to be able to generate xml but not send it, and then have a separate process that does not require user input to send this xml?

           

          If this is the case then you can just create a scheduled event that would run this process, grab xml from db, keep trying to send it until success, delete/mark xml  in db on completion.

          • 2. Re: Capturing XML to be sent to a Web Service
            wasavailable

            Exactly correct and that is the plan.

             

            The problem is that I don't know how to get the xml to be placed in the database record to be sent later.

             

            <cfinvoke> sends the xml and doesn't present it as a variable that I can store in the database.

             

            So, how do I get the xml that would be sent to the web service instead of sending it to the web service?

             

            (This is Al Baker accessing via a different email address.)

            • 3. Re: Capturing XML to be sent to a Web Service
              BKBK Adobe Community Professional & MVP

              Here is a possible scenario.

               

              1) Create database table name: webServiceXml
              Columns: xmlArgID, userID, url, xmlArg, dateSaved, dateSent

               

              xmlArgID is the primary key.
              Datesaved and dateSent are datetimes.
              The dateSent will be filled only after the XML is sent. So, the column dateSent can be null; the other columns are non-null.

               

              2) The initial input page contains the query to save the XML argument:

               

              <cfquery name="saveArg" datasource>
              insert into webServiceXml values... etc., etc.
              </cfquery>

               

              Don't forget to use cfqueryparam

               

              3) As TiGGi has suggested, create a scheduled task that would, at predetermined times:

               

              (i) run a query to get the xml, for example
              <cfquery name="getArg" datasource>
              select xmlArg
              from webServiceXml
              where userID=... and datesaved=...
              </cfquery>

               

              (ii) use the cfinvoke tag to invoke the web service, with argument getArg.xmlArg

               

              (iii) run a query to record the date of the web service invocation
              <cfquery name="savedate" datasource>
              update webServiceXml
              set dateSent = #createODBCDatetime(now())#
              where userID=... and datesaved=....
              </cfquery>

               

              Done.

              • 4. Re: Capturing XML to be sent to a Web Service
                wasavailable Level 1

                Hi,

                 

                I have no problem storing the XML in a table and using it.

                 

                What I don't know how to do is get the XML to be stored in the table.  The <cfinvoke> doesn't let me see the XML is sends to the web service.  It just sends it.  How do I NOT send the XML to the web service, but just acquire it?

                 

                I can call the WSDL and see the definition language describing how to build the XML to be sent.  That doesn't help.  CFInvoke actually DOES build the outgoing XML.  I want THAT XML.  How do I get it so that I can place it in the database table instead of sending it to the web service right away?

                 

                That is what I don't know how to do: capture the outgoing XML.  It is probably very easy and that is why no one is explaining it to me.  They are assuming I already know how to do that part.

                 

                -Al Baker

                • 5. Re: Capturing XML to be sent to a Web Service
                  wasavailable Level 1

                  Well,  I'm guessing no one, even at Adobe, knows how to generate the XML that is going to the Web

                  Service based on the WSDL definition.

                   

                  I'd welcome anyone who can prove me wrong and provide a method of capturing the XML that would be sent to a Web Service based on a WSDL.

                   

                  This doesn't even have to be within ColdFusion.  A site that will take a WSDL url and generate the XML that would be sent would be great.    I found a site that will take a WSDL URL and present a form that can be filled out, but given the XML, I can plug values into the nodes of the generated XML file without a form.  What I want is the actual outgoing XML.

                  • 6. Re: Capturing XML to be sent to a Web Service
                    Joshua Cyr Level 3

                    So what you are saying is that the cfinvode (you haven't posted code) is sending to an external service.  You want to not actually invoke the service but know what the WOULD be sent, and save that for some later use?

                     

                    Why not point the cfinvoke at another cfml page (your own mimic service) that takes the input and save it?

                     

                    Or just build it as xml without invoking the service?

                     

                    Also as an FYI, many of the people replying on forums are not from Adobe.  Just friendly people.

                    • 7. Re: Capturing XML to be sent to a Web Service
                      Adam Cameron. Level 5

                      Also as an FYI, many of the people replying on forums are not from Adobe.  Just friendly people.

                       

                      These forums are not monitored by Adobe.  If ever anyone who happens to work for Adobe ever posts here, they're doing it in their own time.

                       

                      So for all intents and purposes all the people here are just helping out in their spare time.  And, I imagine, less inclined to decide to help someone who has a bit of an attitude, like the OP seems to be adopting.

                       

                      My reason for not replying to the original post is that it didn't make a great deal of sense to me, so I ignored it...

                       

                      --

                      Adam

                      • 8. Re: Capturing XML to be sent to a Web Service
                        Jochem van Dieten Level 4

                        WSDL is pretty much the same as XSD. It may be cumbersome, but it is very well possible to write the XML you need to send by hand.

                         

                        Easier is to download the WSDL to your local system. Then update the service/port/address XML node in the WSDL to a location of your own. Then invoke the webserice. You will now receive the XML at the location of your own, where you can put it in the database.

                        • 9. Re: Capturing XML to be sent to a Web Service
                          wasavailable Level 1

                          Sorry,

                           

                          I do understand that this is a cooperative and extremely friendly group of people.  My frustration was obviously showing and I'm sorry for that and the attitude.

                           

                          As for your answer, Jochem, how very clever!  I'm goig to try that and see how it works.

                           

                          Thanks,

                          • 10. Re: Capturing XML to be sent to a Web Service
                            BKBK Adobe Community Professional & MVP
                            how to generate the XML that is going to the Web Service based on the WSDL definition.

                            I must confess, it's only now I understand what you're looking for. In particular, what you mean by "Capturing XML to be sent to a Web Service".

                             

                            One answer is SOAP. I usually do it as follows:

                             

                            <cfset wsdl_url = "http://www.mydomain.com/myService.cfc?wsdl">

                             

                            <!--- compose the XML as SOAP message --->
                            <cfsavecontent variable="soap_request"><?xml version="1.0" encoding="UTF-8"?>
                            <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
                            <SOAP-ENV:Body>   
                            <theMessage>
                                <someElement>some value</someElement>
                            </theMessage>
                            </SOAP-ENV:Body>
                            </SOAP-ENV:Envelope>
                            </cfsavecontent>

                             

                            <!--- call web service using SOAP --->
                            <cfhttp url="#wsdl_url#" method="post">
                                <cfhttpparam type="header" name="content-type" value="text/xml">
                                <cfhttpparam type="header" name="SOAPAction" value="">
                                <cfhttpparam type="header" name="content-length" value="#len(soap_request)#">
                                <cfhttpparam type="header" name="charset" value="utf-8">
                                <cfhttpparam type="xml" name="message" value="#trim(soap_request)#">
                            </cfhttp>