Thanks Matthew!
I could've sworn I tried that and couldn't get it to work... but, indeed, following 
your example, it works just fine.

I also found the following page: http://devilm.com/archives/000009.html ... concerning 
DUMPing complex variables from webservices.

I was able to revise his code like:

<cffunction name="IsSimpleType" returntype="boolean">
   <cfargument name="type" type="string" required="true">
   <cfset var simpleType = false>
   <cfswitch expression="#arguments.type#">
      <cfcase value="java.lang.String"><cfset simpleType = true></cfcase>
   </cfswitch>
   <cfreturn simpleType>
</cffunction>

<cffunction name="complex2Struct" returntype="struct">
   <cfargument name="complexType" type="any" required="true">
   <cfset var clazz = arguments.complexType.getClass()>
   <cfset var allMethods = clazz.getDeclaredMethods()>
   <cfset var useMethods = StructNew()>
   <cfset var newObj = StructNew()>
   <cfset var methodName = "">
   <cfset var rtnClazz = "">
   <cfset var property = "">
   <cfset var propArray = "">
   <cfloop index="itr" from="1" to="#ArrayLen(allMethods)#">
      <cfset methodName = allMethods[itr].getName()>
      <cfif Left(allMethods[itr].getName(), 3) is "set">
         <cfset methodName = Mid(methodName, 4, Len(methodName) - 3)>
         <cfset useMethods[methodName] = true>
      </cfif>
   </cfloop>
   <cfloop index="itr" from="1" to="#ArrayLen(allMethods)#">
      <cfset methodName = allMethods[itr].getName()>
      <cfif Left(allMethods[itr].getName(), 3) is "get">
         <cfset methodName = Mid(methodName, 4, Len(methodName) - 3)>
         <cfif StructKeyExists(useMethods, methodName)>
            <cfset rtnClazz = allMethods[itr].getReturnType()>
            
            <cfif StructKeyExists(newObj, methodName)>
               <cfif rtnClazz.isArray()>
                  <cfset property = Evaluate("arguments.complexType.#methodName#")>
                  <cfset propArray = ArrayNew(1)>
                  <cfloop index="inr" from="1" to="#ArrayLen(property)#">
                     <cfset propArray[inr] = complex2Struct(property[inr])>
                  </cfloop>
                  <cfset StructInsert(newObj, methodName, propArray, true)>
               <cfelseif NOT rtnClazz.isPrimitive()>
                  <cfset property = Evaluate("arguments.complexType.#methodName#")>
                  <cfset propStruct = StructNew()>
                  <cfloop index="inr" from="1" to="#ArrayLen(property)#">
                     <cfset propStruct[inr] = complex2Struct(property[inr])>
                  </cfloop>
                  <cfset StructInsert(newObj, methodName, propStruct, true)>
               </cfif>
            <cfelse>
               <cftry>
                  <cfif rtnClazz.isPrimitive() or IsSimpleType(rtnClazz.getName())>
                     <cfset StructInsert(newObj, methodName, 
Evaluate("arguments.complexType.#methodName#"))>
                  <cfelse>
                     <cfset StructInsert(newObj, methodName, 
complex2Struct(Evaluate("arguments.complexType.#methodName#")))>
                  </cfif>
                  <cfcatch><!--- can't do anything ---></cfcatch>
               </cftry>
            </cfif>
         </cfif>
      </cfif>
   </cfloop>
   <cfreturn newObj>
</cffunction>


and use it thusly:

        <cfinvoke 
          webservice = "http://webservices.empowered.com/statsws/stats.asmx?WSDL";
          method = "GetTeams"
          returnVariable = "arTestArray">
        
        <CFSET teamStruct = StructNew()>
        <CFSET teamStruct = Duplicate(complex2Struct(arTestArray))>

        <CFOUTPUT>Name of first team is 
#teamStruct.teams["1"].TeamDescription#</CFOUTPUT>


It worked... but, obviously, it put all the data into a structure (and proved to be 
slow)... whereas your solution keeps it in the far more useful array, and is much 
faster.


Thanks again!
-Carl




-----Original Message-----
From: Matthew Westcott [mailto:[EMAIL PROTECTED]
Sent: Wednesday, July 23, 2003 2:18 AM
To: [EMAIL PROTECTED]
Subject: Re: [cf-xml] CFINVOKE, and web services


On 22 Jul 2003 at 15:22, Steinhilber, Carl wrote:

>    <CFINVOKE 
>    webservice="http://webservices.empowered.com/statsws/stats.asmx?WSDL";
>    method="GetTeams"  returnVariable="arTeamsArray">
>    <CFDUMP var="#arTeamsArray#">
> 
> 
> This returns an object
> ("com.empowered.webservices.StatsWS.DataService.ArrayOfTeams"). But I
> seem to be unable to execute any methods of the object or
> deserialize/use the data any other way.
> 
> Help! 
> I'm really just trying to get my feet wet in SOAP and web services...
> but it seems like I can't even get past step one.
> 
> Any pointers would be greatly appreciated!


>From a bit of experimenting, it appears that GetTeams actually needs 
to be called twice, which might be what's catching you out - that is, 
the GetTeams method of the web service returns an ArrayOfTeams 
object, and you have to call GetTeams on the ArrayOfTeams object to 
get an actual array.

The code I've arrived at is:
   <CFINVOKE  
webservice="http://webservices.empowered.com/statsws/stats.asmx?WSDL";
   method="GetTeams"  returnVariable="arTeamsArray">
<CFDUMP
   var="#arTeamsArray#">

<!--- very simple function call,
  to check that calls are working correctly... --->
<cfset stringForm = arTeamsArray.toString()>
<cfoutput>String representation of the object is: 
#stringForm#</cfoutput>

<!--- get the actual array of Teams objects --->
<cfset teams = arTeamsArray.getTeams()>
<cfdump var="#teams#">

<!--- call getTeamDescription on the first Teams object --->
<cfset firstTeamName = teams[1].getTeamDescription()>

<cfoutput>Name of the first team is: #firstTeamName#</cfoutput>



which gives me
 String representation of the object is: 
[EMAIL PROTECTED]

 Name of the first team is: Anaheim Angels


Hope that's enough to get you started,
- Matthew

-----------------------+
cf-xml mailing list
http://torchbox.com/xml/list.cfm

-----------------------+
cf-xml mailing list
http://torchbox.com/xml/list.cfm

Reply via email to