• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Consuming SOAP Web Services

New Here ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

Ok I have a web service that I'm trying to consume in CF9. I'm able to hit the wsdl with SOAPUI and see the results. The results come back in XML format. It basically shows a list of rooms we use as meetings and show the times they are reserved. Here's the CF code I've written for it:

<cfinvoke 

    webservice="http://dwc-dreiman-w7e/WSExchangeMeetingRooms/exchange.asmx?WSDL"

    method="FindResourceDetailForDay"

    returnvariable="FindResourceDetailForDayResponse">

    <cfinvokeargument name="c" value="Deerwood">

    <cfinvokeargument name="d" value="">

</cfinvoke>

<cfoutput>Test value returns #FindResourceDetailForDayResponse#</cfoutput>

However that code returns this: Test value returns org.tempuri.FindResourceDetailForDayResponseFindResourceDetailForDayResult@13d9efc

The information that SoapUI returns in XML format is this:

<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">

               <calendar xmlns="">

                  <Dwc-Room-02 diffgr:id="Dwc-Room-021" msdata:rowOrder="0" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 11:00:00 AM</StartTime>

                     <EndTime>10/6/2010 12:00:00 PM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Construction Meeting</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-02>

                  <Dwc-Room-01 diffgr:id="Dwc-Room-011" msdata:rowOrder="0" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 9:00:00 AM</StartTime>

                     <EndTime>10/6/2010 11:00:00 AM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Leadership Meeting</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-01>

                  <Dwc-Room-01 diffgr:id="Dwc-Room-012" msdata:rowOrder="1" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 12:00:00 PM</StartTime>

                     <EndTime>10/6/2010 2:00:00 PM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Strategic Conversation</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-01>

                  <Dwc-Room-01 diffgr:id="Dwc-Room-013" msdata:rowOrder="2" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 2:00:00 PM</StartTime>

                     <EndTime>10/6/2010 3:00:00 PM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Board Meeting</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-01>

               </calendar>

            </diffgr:diffgram>


How do I go about accessing the information within the parent/child nodes of the XML? This is my first time working with complex webservices in Coldfusion.

TOPICS
Advanced techniques

Views

6.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Oct 09, 2010 Oct 09, 2010

SOAP means you have to send a SOAP XML to the web service. Do something like:

<!--- WSDL --->
<cfset wsdl_url="http://dwc-dreiman-w7e/WSExchangeMeetingRooms/exchange.asmx?WSDL">
        
<cftry>


    <!--- Compose SOAP message to send to Web Service--->
    <cfsavecontent variable="soap"><?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-ins

...

Votes

Translate

Translate
Explorer ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

Rather then <cfoutput>Test value returns #FindResourceDetailForDayResponse#</cfoutput>

Do <cfdump var="#FindResourceDetailForDayResponse#" />

This may then be an CF XML Doc and you should be able to worth with it in CF

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

ColdFusion has several functions for working with XML Document Object Models (DOM).

You can read about working with XML in CF here: http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec133ba-7fd9.html

The function you will get the most use out of is XMLSearch() which will require you to learn a bit of XPath (which is pretty cool, but can be as confusing as regex).

XPath search queries will allow you to dig through complex XML and retrieve nodes that you can then iterate over to accomplish what you probably need.

If you have a more specific question, please reply with it.

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

This:

org.tempuri.FindResourceDetailForDayResponseFindResourceDetailForDayResult@13d9efc

is a Java reference to an object in memory. That object probably contains the XML, as well as methods to interact with that XML.

What do you get when you use CFDUMP to view FindResourceDetailForDayResponse?

To interact with the XML once you get it, CF lets you treat XML documents as if they were nested arrays and structures. So, you can iterate over them using native CF operations and functions. You can also use XML DOM API calls like you would in many other environments. Finally, you can use XPath to match nodes anywhere in your XML.

Dave Watts, CTO, Fig Leaf Software

http://www.figleaf.com/

http://training.figleaf.com/

Fig Leaf Software is a Veteran-Owned Small Business (VOSB) on

GSA Schedule, and provides the highest caliber vendor-authorized

instruction at our training centers, online, or onsite.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

webshot.jpg

That's what I get when I run cfdump

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

Try dumping get_any().

Dave Watts, CTO, Fig Leaf Software

http://www.figleaf.com/

http://training.figleaf.com/

Fig Leaf Software is a Veteran-Owned Small Business (VOSB) on

GSA Schedule, and provides the highest caliber vendor-authorized

instruction at our training centers, online, or onsite.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

It returns back a longer list with what looks like would be functions that would be used for looping thru the XML i.e. "getAllAttributes", "getChildren", "getElementName", "getEnvelope"

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

Well, try calling some of those and see what happens!

Dave Watts, CTO, Fig Leaf Software

http://www.figleaf.com/

http://training.figleaf.com/


Fig Leaf Software is a Veteran-Owned Small Business (VOSB) on

GSA Schedule, and provides the highest caliber vendor-authorized

instruction at our training centers, online, or onsite.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 06, 2010 Oct 06, 2010

Copy link to clipboard

Copied

If it makes any difference here's the entire output I get when I run the WSDL thru SoupUI

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

   <soap:Body>

      <FindResourceDetailForDayResponse xmlns="http://tempuri.org/">

         <FindResourceDetailForDayResult>

            <xs:schema id="calendar" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

               <xs:element name="calendar" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">

                  <xs:complexType>

                     <xs:choice minOccurs="0" maxOccurs="unbounded">

                        <xs:element name="Dwc-Room-02">

                           <xs:complexType>

                              <xs:sequence>

                                 <xs:element name="StartTime" type="xs:string" minOccurs="0"/>

                                 <xs:element name="EndTime" type="xs:string" minOccurs="0"/>

                                 <xs:element name="BusyType" type="xs:string" minOccurs="0"/>

                                 <xs:element name="Subject" type="xs:string" minOccurs="0"/>

                                 <xs:element name="Location" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsException" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsMeeting" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsPrivate" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsRecurring" type="xs:string" minOccurs="0"/>

                              </xs:sequence>

                           </xs:complexType>

                        </xs:element>

                        <xs:element name="Dwc-Room-01">

                           <xs:complexType>

                              <xs:sequence>

                                 <xs:element name="StartTime" type="xs:string" minOccurs="0"/>

                                 <xs:element name="EndTime" type="xs:string" minOccurs="0"/>

                                 <xs:element name="BusyType" type="xs:string" minOccurs="0"/>

                                 <xs:element name="Subject" type="xs:string" minOccurs="0"/>

                                 <xs:element name="Location" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsException" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsMeeting" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsPrivate" type="xs:string" minOccurs="0"/>

                                 <xs:element name="IsRecurring" type="xs:string" minOccurs="0"/>

                              </xs:sequence>

                           </xs:complexType>

                        </xs:element>

                     </xs:choice>

                  </xs:complexType>

               </xs:element>

            </xs:schema>

            <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">

               <calendar xmlns="">

                  <Dwc-Room-02 diffgr:id="Dwc-Room-021" msdata:rowOrder="0" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 11:00:00 AM</StartTime>

                     <EndTime>10/6/2010 12:00:00 PM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Construction Meeting</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-02>

                  <Dwc-Room-01 diffgr:id="Dwc-Room-011" msdata:rowOrder="0" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 9:00:00 AM</StartTime>

                     <EndTime>10/6/2010 11:00:00 AM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Leadership Meeting</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-01>

                  <Dwc-Room-01 diffgr:id="Dwc-Room-012" msdata:rowOrder="1" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 12:00:00 PM</StartTime>

                     <EndTime>10/6/2010 2:00:00 PM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Strategic Conversation</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-01>

                  <Dwc-Room-01 diffgr:id="Dwc-Room-013" msdata:rowOrder="2" diffgr:hasChanges="inserted">

                     <StartTime>10/6/2010 2:00:00 PM</StartTime>

                     <EndTime>10/6/2010 3:00:00 PM</EndTime>

                     <BusyType>Busy</BusyType>

                     <Subject>Board Meeting</Subject>

                     <Location/>

                     <IsException>False</IsException>

                     <IsMeeting>False</IsMeeting>

                     <IsPrivate>False</IsPrivate>

                     <IsRecurring>False</IsRecurring>

                  </Dwc-Room-01>

               </calendar>

            </diffgr:diffgram>

         </FindResourceDetailForDayResult>

      </FindResourceDetailForDayResponse>

   </soap:Body>

</soap:Envelope>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 07, 2010 Oct 07, 2010

Copy link to clipboard

Copied

What you are getting back is actually a http response and you need to

get at the soap body inside it

so for my returnVariable which I've called httpResponse - I do the following

        <cfif find( "200", #httpResponse.statusCode# )>

                <!--- Parse the XML SOAP response. --->
                <cfset soapResponse = xmlParse( #httpResponse.fileContent# ) />
               
                <!-- write a copy of the response to the file system -->
                <cffile action="write" 
                file="#session.server_root#/xmlOrders/#now()_response.xml"
                output="#soapResponse#" >
    
                <!---
                    Query for the response nodes using XPath. Because the
                    SOAP XML document has name spaces, querying the document
                    becomes a little funky. Rather than accessing the node
                    name directly, we have to use its local-name().
                --->
                <cfset responseNodes = xmlSearch(
                    #soapResponse#,
                    "//*[ local-name()='SOL_Acknowledgement']"
                    ) />

     </cfif>

Hope that helps

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 07, 2010 Oct 07, 2010

Copy link to clipboard

Copied

Here's my latest attempt. It seems to blow up around the CF struct-style XML node access attempt at the very bottom. The error I get is "

Element NAME.XMLTEXT is undefined in a Java object of type class coldfusion.xml.XmlNodeMap referenced as ''

<cfsavecontent variable="soapBody">

<cfoutput>

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

            xmlns:xsd="http://www.w3.org/2001/XMLSchema"

            xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

<soap:Body>

<FindResourceDetailForDay xmlns="http://tempuri.org/">

<c>Deerwood</c>

      <d></d>

    </FindResourceDetailForDay>

  </soap:Body>

</soap:Envelope>

</cfoutput>

</cfsavecontent>

<cfhttp

url="http://webservice/WSExchangeMeetingRooms/exchange.asmx"

method="post"

result="httpResponse">

<cfhttpparam

type="header"

name="SOAPAction"

value="http://tempuri.org/FindResourceDetailForDay"

/>

<cfhttpparam

type="header"

name="accept-encoding"

value="no-compression"

/>

<cfhttpparam

type="xml"

value="#trim( soapBody )#"

/>

</cfhttp>

<cfif find( "200", httpResponse.statusCode )>

<!--- Parse the XML SOAP response. --->

<cfset soapResponse = xmlParse( httpResponse.fileContent ) />

<cfset responseNodes = xmlSearch(

soapResponse,

"//*[ local-name() = 'FindResourceDetailForDayResponse' ]"

) />

<cfoutput>

Code: #responseNodes[ 1 ].Code.xmlText#

<br />

Success: #responseNodes[ 1 ].Message.xmlText#

</cfoutput>

</cfif>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Oct 07, 2010 Oct 07, 2010

Copy link to clipboard

Copied

I would highly recommend using cfdump while you are debugging this issue. It will keep you away from getting sidetracked from the real issue. So instead of cfoutput'ing your variables just cfdump the entire structure. That way you can get a better picture of what is happening (or not).

Instead of this:

<cfoutput>

Code: #responseNodes[ 1 ].Code.xmlText#

<br />

Success: #responseNodes[ 1 ].Message.xmlText#

</cfoutput>

Do this:

<cfdump var="#responseNodes#">

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2010 Oct 09, 2010

Copy link to clipboard

Copied

SOAP means you have to send a SOAP XML to the web service. Do something like:

<!--- WSDL --->
<cfset wsdl_url="http://dwc-dreiman-w7e/WSExchangeMeetingRooms/exchange.asmx?WSDL">
        
<cftry>


    <!--- Compose SOAP message to send to Web Service--->
    <cfsavecontent variable="soap"><?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>
                 <ns:requestParameterName soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns="http://your_own_namespace_url">
                        <c xsi:type="xsd:string">bkbk</c>
                      <d xsi:type="xsd:string">test message from bkbk</d> 
                  </ns:requestParameterName>
              </soapenv:Body>
          </soapenv:Envelope>
    </cfsavecontent>


        <!--- Invoke web service to send message--->
        <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)#">
            <cfhttpparam type="header" name="charset" value="utf-8">
            <cfhttpparam type="xml" name="message" value="#trim(soap)#">
        </cfhttp>
        <p><cfoutput>#xmlFormat(cfhttp.fileContent)#</cfoutput> </p>
       
    <cfcatch type="any">
        <cfdump var="#cfcatch#">
    </cfcatch>
</cftry>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 11, 2010 Oct 11, 2010

Copy link to clipboard

Copied

Thanks BKBK, that worked for me. Now I'm getting the XML returned from the webservice. Now I just need to be able to query the XML data but I think I can find/figure that out on my own. Thanks everyone for the help.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Sep 14, 2011 Sep 14, 2011

Copy link to clipboard

Copied

I was having this same issue and found a way to get at the values while still using the cfinvoke method instead of using cfhttp.  To re-iterate when I made a cfinvoke call to the web service and dumped the result I would see an object dump with methods but no values (not the soap response I was expecting).  You are able to retrieve the values from the service call by utilizing those methods that you see returned in the object.  So for example, in this post a cfinvoke call was made to the web service and the result was stored in return variable "FindResourceDetailForDayResponse".  The cfdump that was included shows the methods returned for that web service.  In order to get the actual data from the call you can reference them like this for simple values:  FindResourceDetailForDayResponse.getSimpleValue().  For complex values (like in the example from this post) you must dig a little deeper.  If you keep cfdump'ing the returned methods you will finally get to the simple values.  Then it is just a matter of calling each method in turn, like:  FindResourceDetailForDayResponse.get_any().getStartTime() and FindResourceDetailForDayResponse.get_any().getEndTime() etc.

I know this is an old post but I just wanted to get this info out here because I haven't seen it mentioned anywhere else.  You can certainly call the webservice using cfhttp as others have mentioned but then you need to deal with the resulting XML object.  By calling the methods as I have shown you can access the values directly without the need to traverse the XML tree.  If there is an issue with processing the soap response in this way then please let me know.  It seems to be working for me.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 23, 2011 Sep 23, 2011

Copy link to clipboard

Copied

LATEST

Miguel - one thing I would watch out for is if one of the properties associated with a getter methods does not contain a value, you will get a NULL value back.  In ColdFusion setting a variable to a NULL value will remove that variable from the memory space and give you a variable is not defined error when you try to use it.  Typically this is not a huge issue, but .NET based web services are the worst at this sort of thing (returning NULL values, that is).  I always caution users who are consuming web services using the <cfinvoke> method to check all of their getMethod() calls for NULL values or use an isdefined() check before using the variable.  Rolling that checking logic into a UDF makes it a little easier to implement.

One advantage that the SOAP method has is that since you are dealing with native XML, it is a little easier to handle missing elements/attributes from your web service call.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation