希望这是一个" DOH"但我无法弄清楚为什么会这样。我正在使用服务对象来获取Google的Directory API中的组成员。创建服务对象后,我使用以下行来测试
<cfset themembers = groupservice.members().list("[My Group Key]").execute()>
<cfdump var="#themembers#">
<cfoutput>
Isnull? #isNull(themembers.etag)#<br />
SKExists? #structKeyExists(themembers,"etag")#<br />
Is Defined? #isDefined("themembers.etag")#
</cfoutput>
查看转储我可以看到etag字段中有数据以及一组成员。但是,当我尝试输出键值时,我收到了一个未定义的错误。我写了一个测试输出行,它显示为NULL,并且在键存在时没有定义。
当变量的转储清楚地显示数据时,这怎么可能?我在这里缺少什么?
@Leigh
<cfdump var="#groupservice.members()#">
<cfdump var="#groupservice.members().list('[groupkey]')#">
以下是上述2行的转储。 list方法只返回我传入的groupkey名称 - 它只在我运行execute方法之后才能实际获得成员列表(在第一个图像中输出),但就像etag一样 - 它告诉我成员是未定义的。
答案 0 :(得分:2)
简答:
显然,这属于&#34;永远不会信任CFDump的一般规则。有时它是谎言。&#34;例如,变量themembers
实际上不是一个结构。它是Members类的一个实例。不要使用点表示法,而是尝试调用类的相关方法:
<cfset eTag = themembers.getETag()>
<cfset membersArray = themembers.getMembers()>
..
更长的答案:
虽然CFDump是一个很好的调试工具,但它倾向于支持&#34;漂亮的演示&#34;超过准确性,所以你不能总是相信你所看到的。它将themembers
显示为&#34; struct&#34;的原因是因为ColdFusion automatically matches Java types to ColdFusion types。如果你看一下Members的类层次结构,你可以看到它实现java.util.Map(通过AbstractMap),它自动匹配CF结构。因此,为什么CFDump(误导性地)将其显示为一个。
- com.google.api.services.admin.directory.model.Members
- com.google.api.client.json.GenericJson
- com.google.api.client.util.GenericData
- java.util.AbstractMap
- java.lang.Object
尽管java对象与结构类似,但在某些方面,它们并不相同。因此,某些功能的结果可能与您通常对结构的预期不同,这就是这里发生的事情。即,您可以使用结构键查看某些属性名称,但不能直接访问键/属性值。
那就是说,技术上你应该能够访问&#34; eTag&#34;和&#34;成员&#34;带点符号的属性。原因是CF对某些Java对象应用了一些语法糖,以允许使用点表示法直接访问属性。就好像它们是常规结构键一样。
ColdFusion可以自动调用get_PropertyName_()和 set_PropertyName_(value)方法,如果Java类符合 JavaBeans模式。因此,您可以设置或获取属性 直接引用它,而不必显式调用方法。
但是,正如文档后面所述,有一些例外。这个类似乎是其中之一。因此,您需要显式调用相应的get PropertyName()方法。最终,这可能是最好的做法,因为直接访问并不总是有效。
示例:的
// Simulate Members object
obj = createObject("java", "com.google.api.services.admin.directory.model.Members").init();
// Initialize property values
obj.setEtag("If you are seeing this text, it worked.");
obj.setMembers( [] );
writeOutput("<br>IsNull? "& isNull(obj.etag));
writeOutput("<br>Key List: "& structKeyList(obj));
writeOutput("<br>Exists? "& structKeyExists(obj, "etag"));
writeOutput("<br>IsDefined? "& IsDefined("obj.etag"));
writeOutput("<br>getETag(): "& obj.getETag());
writeDump(var=obj.getMembers(), label="getMembers()");
结果:
IsNull? YES
Key List: etag,members
Exists? YES
IsDefined? NO
getETag(): If you are seeing this text, it worked.
getMembers(): (empty array)
答案 1 :(得分:0)
我解决未定义结构值的方法是使用structKeyArray来构造结构中的键的数组。然后,在数组上循环以检查struct键是否存在。示例:
//result is a structure which can have undefined values
myAry = structKeyArray(result);
myLen = arrayLen(myAry);
for (i=1; i <= myLen;i=i+1){
if(!structKeyExists(result, "#myAry[i]#")){
result[myAry[i]] = "";
}
}
当然,您可能不需要空白字符串,但是在我的情况下,这就是我一直在寻找的空白字符串。