变量转储显示数据但返回为未定义

时间:2017-02-14 16:27:45

标签: coldfusion google-admin-sdk google-directory-api

希望这是一个" 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>

代码的结果输出如下screenshot

查看转储我可以看到etag字段中有数据以及一组成员。但是,当我尝试输出键值时,我收到了一个未定义的错误。我写了一个测试输出行,它显示为NULL,并且在键存在时没有定义。

当变量的转储清楚地显示数据时,这怎么可能?我在这里缺少什么?

@Leigh

<cfdump var="#groupservice.members()#">
<cfdump var="#groupservice.members().list('[groupkey]')#">

以下是上述2行的转储。 list方法只返回我传入的groupkey名称 - 它只在我运行execute方法之后才能实际获得成员列表(在第一个图像中输出),但就像etag一样 - 它告诉我成员是未定义的。 sshot1

2 个答案:

答案 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]] = "";
     }
    }

当然,您可能不需要空白字符串,但是在我的情况下,这就是我一直在寻找的空白字符串。