15 Replies Latest reply on Dec 2, 2014 4:26 AM by BKBK

    How to get Soap Request xml in application.cfc

    HaroonTyagi

      Hi

      if api getting soap request using cfhttp like below:

      <cfxml variable="mydata">

      <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

         <soapenv:Header />

         <soapenv:Body>

             <ns:service_soap_call soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

              <login>test</login>

              <password>test</password>

            </ns:service_soap_call>

         </soapenv:Body>

      </soapenv:Envelope>

      </cfxml>

       

        <cfhttp url="http://sm.iclp-dubai.ae/research/wsdl/MyPointsBank.cfc?wsdl" method="post" charset="utf-8" result="myresult">

             type" value="text/xml">

              <cfhttpparam type="header" name="SOAPAction" value="">

             <cfhttpparam name="soapInput" type="xml" value="#trim(mydata)#"/>

      </cfhttp>

       

      then how to get Soap Request in application cfc.

      like :

      <cfif IsSOAPRequest() >

        <cfset soapreq = GetSOAPRequest() />

      </cfif>

       

      I want to validate the soap xml Request before calling targeted CFC.

      Any suggestion!.

        • 1. Re: How to get Soap Request xml in application.cfc
          BKBK Adobe Community Professional & MVP

          Why would you want to do that in Application.cfc? The whole idea behind the design of IsSOAPRequest() is that it is to be used within a CFC to indicate when the CFC is called as a web service. In your case, it would be appropriate to put it in MyPointsBank.cfc instead.

          • 2. Re: How to get Soap Request xml in application.cfc
            HaroonTyagi Level 1

            Thanks BKBK,

             

            I want to validate soap request before calling the targeted CFC method.
            Consider this example if the soap request without the method body like below:

             

            <cfxml variable="mydata">

            <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

               <soapenv:Header />

               <soapenv:Body>

                  

               </soapenv:Body>

            </soapenv:Envelope>

            </cfxml>

             

            then how to validate this and display proper fault code. In this case coldfusion generating a below exception:

             

            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

               <soapenv:Body>

                  <soapenv:Fault>

                     <faultcode>soapenv:Server.userException</faultcode>

                     <faultstring>java.lang.Exception: Body not found.</faultstring>

                     <detail>

                        <ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/">java.lang.Exception: Body not found.

            at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java....

             

            but I wan to display proper fault code.

             

            Any Idea!

            • 3. Re: How to get Soap Request xml in application.cfc
              BKBK Adobe Community Professional & MVP

              What you show (mydata) is just an XML variable. It is not  a SOAP request. A SOAP request is, for example, a CFC method whose access is 'remote'.

              • 4. Re: How to get Soap Request xml in application.cfc
                HaroonTyagi Level 1

                BKBK Thanks,

                 

                Please consider that CFC component is ready like below:

                <cfcomponent output="no">

                <cffunction name="service_soap_call" access="remote" output="no" returntype="any" >

                      <cfargument name="argument1">

                     ................................    

                </cfcomponent>

                 

                Now I am accessing this CFC via CFHTTP or vai SoapUI like below:

                <cfxml variable="mydata">
                        <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wor="https://www.worldmilesafrica.com">
                   <soapenv:Header/>
                   <soapenv:Body>    
                   </soapenv:Body>
                </soapenv:Envelope>
                </cfxml>

                  <cfhttp url="#WSDL_URL#" method="post" charset="utf-8" result="myresult">
                  <cfhttpparam type="header" name="content-type" value="text/xml">
                        <cfhttpparam type="header" name="SOAPAction" value="">
                  <cfhttpparam name="soapInput" type="xml" value="#trim(mydata)#"/>
                </cfhttp>
                   
                    <cfdump var="#myresult.FileContent#">

                 

                It will generate below exception:

                 

                <?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Server.userException</faultcode> <faultstring>java.lang.Exception: Body not found.</faultstring>................

                 


                How can I handle this type of exception and display my customize fault code. Any idea will be very helpful..

                • 5. Re: How to get Soap Request xml in application.cfc
                  BKBK Adobe Community Professional & MVP

                  You could just test whether the SOAP body is blank. If so, do a throw, returning the error message. Something like this,

                   

                  <cfset var inputXML = xmlParse(arguments.soapInput)>

                  <cfset var soapBodyText="">

                  <cfset var noBodyTextError="">

                   

                  <cfset soapBodyText = xmlSearch(inputXML,"//soapenv:Body/text()")[1].xmlValue>

                   

                  <cfsavecontent variable="noBodyTextError"><?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Server.userException</faultcode> <faultstring>java.lang.Exception: Body not found.</faultstring></cfsavecontent>

                   

                  <cftry>

                      <cfif trim(soapBodyText) is "">

                          <cfthrow>

                      </cfif>

                  <cfcatch type="any">

                      <cfreturn noBodyTextError>

                  </cfcatch>

                  </cftry>

                  • 6. Re: How to get Soap Request xml in application.cfc
                    HaroonTyagi Level 1

                    BKBK, You know very well all soap request directly calling CFC Component, right

                     

                    If this is my CFC component then could you explain me please where I will check the soap body and how

                    <cfcomponent output="no">

                    <cffunction name="service_soap_call" access="remote" output="no" returntype="any" >

                          <cfargument name="argument1">

                         ................................    

                    </cfcomponent>

                    • 7. Re: How to get Soap Request xml in application.cfc
                      BKBK Adobe Community Professional & MVP

                      In the function, of course. You can tell from the use of 'var', 'arguments' and 'cfreturn'.

                      • 8. Re: How to get Soap Request xml in application.cfc
                        HaroonTyagi Level 1

                        My Dear BKBK if you check request xml above, then there is no function name(cfc component function: service_soap_call) and function body. So flow will not come inside a function and code will not execute.

                         

                        Please could you make simple component like below:

                        Webservice.cfc

                         

                        <cffunction name="service_soap_call" access="remote" output="no" returntype="any" >

                              <cfargument name="str">

                             <cfreturn arguments.str>

                           </cffunction>

                        </cfcomponent>

                        if CFC component on your localhost then you can access web service url: http://localhost/Webservice.cfc?wsdl

                        then call this web service via this localhost url in your cfm with below below code:

                        CFhttp.cfm

                         

                        <cfxml variable="mydata">
                                <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wor="https://www.worldmilesafrica.com">
                           <soapenv:Header/>
                           <soapenv:Body>    
                           </soapenv:Body>
                        </soapenv:Envelope>
                        </cfxml>

                          <cfhttp url="http://localhost/Webservice.cfc?wsdl" result="myresult">
                          <cfhttpparam type="header" name="content-type" value="text/xml">
                                <cfhttpparam type="header" name="SOAPAction" value="">
                          <cfhttpparam name="soapInput" type="xml" value="#trim(mydata)#"/>
                        </cfhttp>

                        <cfdump var="#myresult.fileContent#">

                         

                        Please can try this example so you will have clear picture and understand correctly.

                        I am using ColdFusion 8 but I have checked in ColdFusion 11 same error.

                        thanks

                        • 9. Re: How to get Soap Request xml in application.cfc
                          BKBK Adobe Community Professional & MVP

                          HaroonTyagi wrote:

                           

                          if you check request xml above, then there is no function name(cfc component function: service_soap_call) and function body.

                          No function name and body? This is confusing. You did define the following named function:

                           

                          <cffunction name="service_soap_call" access="remote" output="no" returntype="any" >

                          </cffunction>

                          • 10. Re: How to get Soap Request xml in application.cfc
                            HaroonTyagi Level 1

                            BKBK This function defined in cfc component not in xml file inside cfm. if request doesn't have the function value then how the cfc component will identify which function need to call, finally will return the error that function is not defined.

                             

                            Untitled.png

                            • 11. Re: How to get Soap Request xml in application.cfc
                              BKBK Adobe Community Professional & MVP

                              Let me see whether I understand. Are you attempting to achieve something like this:

                               

                              test.cfc

                              <cfcomponent output="no">

                              <cffunction name="testFunction" returntype="any" access="remote">

                              <cfargument name="soapInput">

                              <cfset var inputXML = arguments.soapInput>

                              <cfset var soapBodyText="">

                              <cfset var noBodyTextError="">

                              <cftry>

                                  <cfset soapBodyText = xmlSearch(inputXML,"//soapenv:Body/text()")[1].xmlValue>

                               

                                  <cfsavecontent variable="noBodyTextError"><?xml version="1.0" encoding="utf-8"?><soapenv:Envelope     xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Server.userException</faultcode> <faultstring>java.lang.Exception: Body not found.</faultstring></cfsavecontent>

                                 

                                  <cfif trim(soapBodyText) is "">

                                  <cfthrow>

                                  </cfif>

                                  <cfreturn inputXML>

                              <cfcatch type="any">

                              <cfreturn noBodyTextError>

                              </cfcatch>

                              </cftry>

                              </cffunction>

                              </cfcomponent>

                               

                              tester.cfm

                              <cfxml variable="mydata">

                                      <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wor="https://www.worldmilesafrica.com">

                                 <soapenv:Header/>

                                 <soapenv:Body>

                                 </soapenv:Body>

                              </soapenv:Envelope>

                              </cfxml>

                               

                              <cfinvoke webservice = "http://127.0.0.1:8500/workspace/wsTest/test.cfc?wsdl"

                                        method = "testFunction"

                                         returnVariable = "result">

                                     <cfinvokeargument name="soapInput" value="#trim(mydata)#" >

                              </cfinvoke>

                               

                              <cfdump var="#result#">

                              • 12. Re: How to get Soap Request xml in application.cfc
                                HaroonTyagi Level 1

                                Hi BKBK yes but as you know web service can call from any language so please use the

                                standard method via http like below

                                <cfxml variable="xmldata">

                                <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wor="https://www.worldmilesafrica.com">

                                   <soapenv:Header/>

                                   <soapenv:Body>

                                   </soapenv:Body>

                                </soapenv:Envelope>

                                </cfxml>

                                  <cfhttp url="http://127.0.0.1:8500/workspace/wsTest/test.cfc?wsdl" method="post" result="myresult">
                                  <cfhttpparam type="header" name="content-type" value="text/xml">
                                        <cfhttpparam type="header" name="SOAPAction" value="">
                                  <cfhttpparam name="soapInput" type="xml" value="#trim(xmldata)#"/>
                                </cfhttp>   

                                    <br />
                                    <cfset mydata = xmlParse(#myresult.fileContent#) >
                                    <cfdump var="#mydata#">

                                • 13. Re: How to get Soap Request xml in application.cfc
                                  BKBK Adobe Community Professional & MVP

                                  Yes, you may call a SOAP web service like that, using cfhttp. I would expand the call to:

                                   

                                  <cfxml variable="mydata">

                                          <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" der/>

                                     <soapenv:Body>

                                     </soapenv:Body>

                                  </soapenv:Envelope>

                                  </cfxml>

                                   

                                  <cfhttp url="http://127.0.0.1:8500/workspace/wsTest/test.cfc?wsdl" method="post" result="myresult" >

                                      <cfhttpparam type="header" name="content-type" value="text/xml" />

                                      <cfhttpparam type="header" name="content-length" value="#Len(Trim(mydata))#" />

                                      <cfhttpparam type="header" name="charset" value="utf-8" />

                                      <cfhttpparam type="header" name="SOAPAction" value="">

                                      <cfhttpparam type="xml" name="message" value="#trim(mydata)#">

                                  </cfhttp>

                                   

                                  <cfdump var="#myresult.FileContent#">

                                   

                                  I should add that it is unnecessary to manually code the error-handling in the CFC. If there are any errors, ColdFusion will generate and return them automatically.

                                  • 14. Re: How to get Soap Request xml in application.cfc
                                    HaroonTyagi Level 1

                                    Yes BKBK, but we can not show ColdFusion generated errors to user because that error is not user friendly and user will never identify what is the problem exactly.

                                    Untitled.png

                                    Please look below errors which is generated by ColdFusion automatically

                                    <soapenv:Fault>

                                             <faultcode>soapenv:Server.userException</faultcode>

                                             <faultstring>java.lang.Exception: Body not found.</faultstring>

                                             <detail>

                                                <ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/">java.lang.Exception: Body not found.

                                    at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:121).......... .........

                                     

                                    I want to show proper erros like this

                                    <soapenv:Fault>

                                             <faultcode>11001</faultcode>

                                             <faultstring>method definition does not exist</faultstring>

                                          -------------

                                     

                                    All technology have separate fault class and method through that can generate easily original fault code..

                                    • 15. Re: How to get Soap Request xml in application.cfc
                                      BKBK Adobe Community Professional & MVP

                                      @HaroonTyagi

                                       

                                      I am now able to make time so that we can explore this question in full. First of all, let us get some assumptions and misconceptions out of the way.

                                       

                                      For example, you insisted that one should be able to throw and handle a custom exception when invoking a web service using cfhttp. This expectation may have a basis in the client-server model, where methods are explicitly invoked, but it has no basis here.

                                       

                                      In fact, Adobe ColdFusion owes you no explanation about the use of cfhttp to invoke SOAP web services. Neither can it guarantee anything about this usage. The reason is that, using the post method of cfhttp to invoke web services is an undocumented method. By this, I mean that, although creative developers have discovered that it can be so used, it was not designed for that purpose.

                                       

                                      The officially documented native Coldfusion ways to consume a web service are by means of <cfobject>, <cfinvoke> and createobject(), or their various script/tag equivalents. There is one big difference between these functionalities and <cfhttp method="post">. If the web service has a compulsory method, then they must call it. Neither <cfobject>, <cfinvoke> nor createobject() can intereact with a web service without explicitly calling its methods.

                                       

                                      That is in keeping with the principles of the client-server model of computing. In this case, the web service is the server and the calling application the client. The client makes a request to the service by invoking its method; the server responds by means of a method return.

                                       

                                      In contrast, a client using <cfhttp method="post"> may interact with a web service without calling its methods. For example, by posting a SOAP message containing a blank body to the service, as you have done. In that case, you should not expect to be able to apply client-server validation methods, as these necessarily require that methods be explicitly called. In fact, in the client-server model, the method or function is the web service proper.

                                       

                                      Therefore, you should perform custom validation in your CFC with the assumption that the service will be consumed by means of <cfobject>, <cfinvoke> or createobject(). There is a further advantage of assuming these will be used, instead of <cfhttp method="post">. The calls based on <cfobject>, <cfinvoke> and createobject() are the Coldfusion equivalents of calls that will be made from other languages, like PHP, .NET, and so on.