变量转储显示数据,但以未定义形式返回

问题描述 投票:3回答:2

希望这是一个“ 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,并且在关键DOES存在时未定义。

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

@ Leigh

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

这里是上述两行的转储。 list方法只是返回我要传入的groupkey名称-只有在运行execute方法之后,我才真正获取成员列表(在第一张图片中输出),但是与etag一样-它告诉我成员未定义。sshot1

coldfusion google-admin-sdk google-directory-api
2个回答
2
投票

简短回答:

显然,这属于“永不信任CFDump。有时会说谎。”举例来说,变量themembers并不是一个真正的结构。它是Members类的实例。而不是使用点符号,请尝试调用该类的相关方法:

<cfset eTag = themembers.getETag()>
<cfset membersArray = themembers.getMembers()>
..

更长的答案:

尽管CFDump是一个很好的调试工具,但它倾向于倾向于“漂亮的呈现”而不是准确性,因此您不能总是信任所看到的。之所以将themembers显示为“结构”,是因为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对象与结构相似,但在某些方面,它们不是一回事。因此,某些功能的结果可能与您通常期望的结构有所不同,这就是这里发生的情况。即,您可以查看某些属性名称,就像使用结构键一样,但不能直接访问键/属性值。

也就是说,从技术上讲,您应该能够使用点表示法访问“ eTag”和“ members”属性。原因是CF对某些Java对象应用了一些语法糖,以允许使用点表示法直接访问属性。就像它们是常规结构键一样。

ColdFusion可以自动调用get_PropertyName_()和如果Java类符合set_PropertyName_(value)方法,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)

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

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

© www.soinside.com 2019 - 2024. All rights reserved.