Copy link to clipboard
Copied
I am experimenting to see if it is possible for a ColdFusion web service method to somehow return another object of some sort. I am not having any luck with either my code or searching Google, but I wanted to ask before I gave this up as impossible.
My last experiment looked something like this:
webservice-test.cfm
<cfset testObj = createObject("component","webservice")>
<cfoutput>#testObj.getID()#</cfoutput><hr />
<cfoutput>#testObj.getObj().myFunction("george")#</cfoutput><hr />
<cfdump var="#testObj.getObj()#"><hr />
<cfdump var="#testObj#"><cfset testWS = createObject("webservice","http://localhost/webservice.cfc?wsdl")>
<cfoutput>#testWS.getID()#</cfoutput><hr />
<cfdump var="#testWS.getObj()#"><hr />
<cfdump var="#testWS#">
webservice.cfc
<cfcomponent>
<cfproperty name="ID" default="10" type="numeric">
<cfproperty name="obj" type="webservice2">
<cfset variables.ID = "12">
<cfset variables.obj = createObject("component","webservice2")>
<cffunction name="getID" access="remote" returntype="numeric">
<cfreturn variables.ID>
</cffunction>
<cffunction name="getObj" access="remote" returntype="webservice2">
<cfreturn variables.obj>
</cffunction>
</cfcomponent>
webservice2.cfc
<cfcomponent>
<cffunction name="myFunction" access="remote" returntype="string">
<cfargument name="myArgument" type="string" required="yes">
<cfset myResult=arguments.myArgument>
<cfreturn myResult>
</cffunction>
</cfcomponent>
This produces the include results.
As can be seen the top portion of the code that access the nested components locally works exactly as expected.
The lower portion of the first file that accesses the nested components as a web service produce an empty string for the method that is supposed to reference the second cfc file. Is that what happens if one tries to nest objects in a web service, or am I doing something wrong.
Copy link to clipboard
Copied
Updated code:
webservice-test.cfm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Complex Webservice Tests</title>
</head>
<body>
<div style="width: 39.5%; float:left;">
<cfset testObj = createObject("component","webservice")>
getID: <cfoutput>#testObj.getID()#</cfoutput><hr />
getFoo: <cfoutput>#testObj.getObj().getFoo()#</cfoutput><hr />
<cfset testObj.getObj().setFoo("New Stuff")>
getFoo: <cfoutput>#testObj.getObj().getFoo()#</cfoutput><hr />
<cfdump var="#testObj.getObj()#" expand="yes"><hr />
<cfdump var="#testObj#" expand="yes">
</div>
<div style="width: 59.5%; float:right;">
<cfset testWS = createObject("webservice","http://localhost/webservice.cfc?wsdl")>
<cfset nestedObj = testWS.getObj()>
getID: <cfoutput>#testWS.getID()#</cfoutput><hr />
getFoo: <cfoutput>#nestedObj.getFoo()#</cfoutput><hr />
<cfset nestedObj.setFoo("New Stuff")>
getFoo: <cfoutput>#nestedObj.getFoo()#</cfoutput><hr />
<cfdump var="#nestedObj#">
<cfdump var="#testWS#">
</div>
</body>
</html>
webservice.cfc
<cfcomponent>
<cfproperty name="ID" default="10" type="numeric">
<cfproperty name="obj" type="myobject">
<cfset variables.ID = "12">
<cfset variables.obj = createObject("component","myobject")>
<cffunction name="getID" access="remote" returntype="numeric">
<cfreturn variables.ID>
</cffunction>
<cffunction name="getObj" access="remote" returntype="myobject">
<cfreturn variables.obj>
</cffunction>
</cfcomponent>
myobject.cfc
<cfcomponent>
<cfproperty name="foo" default="bar" type="string">
<cfset variables.foo = "bar">
<cffunction name="setFoo" returntype="void">
<cfargument name="foo" type="string">
<cfset variables.foo = arguments.foo>
</cffunction>
<cffunction name="getFoo" returntype="string">
<cfreturn variables.foo>
</cffunction>
</cfcomponent>
This code is now working mostly as I would expect it to, accept for some strange reason when the nested myObject.cfc is called from the webservice code, the getFoo() function will not return the default value. It works properly after setFoo() is used to set a value, but not with the initial default value.
I find this rather strange.
Copy link to clipboard
Copied
I find this rather strange.
I don't think it strange. The entity createObject("component","myobject") is just a static type, representing the myobject type. It isn't an instance.
To create an instance that holds the field variables, use an init, as follows:
<cfcomponent>
<cffunction name="init" returntype="myobject">
<cfset variables.foo = "bar">
<cfreturn this></cffunction>
<cffunction name="setFoo" returntype="void">
<cfargument name="foo" type="string">
<cfset variables.foo = arguments.foo>
</cffunction>
<cffunction name="getFoo" returntype="string">
<cfreturn variables.foo>
</cffunction>
</cfcomponent>
Having said that, I think the best way to send a CFC on the wire is by serializing it (as a text file!)