追加到 JSON 数组中的 JSON 数组 ColdFusion

Append to JSON array within an JSON array ColdFusion

这是以下问题的后续问题:

昨天已经回答了这个问题并且效果很好(谢谢 Kevin B. 和 Leigh!)。但是,今天早上我从中提取 JSON 数据的应用程序给我带来了麻烦。 有时,根据我请求的数据,它 returns 整个 JSON 作为一个数组,如下所示:

[
   {
      "loginHosts": [
         "server1.example.com"
      ],
      "sudoHosts": [
         "server1.example.com"
      ],
      "CPG": [
         "my_group"
      ],
      "mail": "myuser@example.com",
      "loginShell": "/bin/bash"
   }
]

我不知道为什么那个应用程序会这样做。如果我知道这是可能的,我会将该信息添加到我之前的问题中,我很抱歉。

我寻找解决方案的尝试首先将我引向这里:Using JSON Data with Coldfusion。将 JSON 数组作为集合循环似乎可行,但前提是数组值的 none 为 Null。我认为如果我将它用于所有 JSON 字段,就像在上一个问题中那样使用这段代码会起作用:

<cfif NOT structKeyExists(myStruct, 'sudoHosts') OR NOT isArray(myStruct.sudoHosts)> 
  <cfset myStruct.sudoHosts = []>
</cfif>

事实并非如此。我不断得到:

Error: Can't cast Complex Object Type Array to String

查看调试输出,Lucee 确实抛出了这个:string Use Built-In-Function "serialize(Array):String" to create a String from Array。我做了更多挖掘并找到了这篇文章:Railo tip: store complex data by using serialize(data)。可悲的是,Null 值再次出现。另外,我的理解是serialize()evaluate()类似,不推荐。

我将继续寻找解决方案,但一如既往地非常感谢您的帮助!

-- 编辑 --

我看到了这个线程:ColdFusion JSON object vs array of objects。我注意到问题中的 JSON 是一个数组 [],我将答案应用到我的代码中,但我仍然 运行 进入 Null 问题。我想我不知道如何检查嵌套的 Null 值。 :(

一步一个脚印。

理想情况下,您应该确定为什么 响应不同。由于您说这些差异通常对应于 您的 请求中的不同内容,这强烈表明您可能忽略(或可能误解)远程 API 中的某些内容。我建议重新审查 API 以确定 "something",以便找出正确的方法。否则,当您继续调整代码以处理每个 "new" 情况时,代码将很快变得难以管理且效率低下。

如果由于某种原因 API 确实 在没有正当理由的情况下返回不同的结果,你能做的最好的事情就是根据你 expect 并在收到其他东西时优雅地失败。首先列出预期的可能性:

  1. 响应是包含特定键的单一结构或
  2. 响应是包含特定键的结构数组

基于以上内容,您可以使用IsArray and IsStruct函数来确定响应的格式,并进行相应的处理。首先检查反序列化的对象。如果是数组,提取第一个元素的结构(注意,我假设数组只包含一个元素,如示例中。如果它可以包含多个元素,则需要额外处理).

<cfset data = deserializeJson(originalJSON)>
....
<!--- Extract structure from first element of array --->
<cfif IsArray(data) && arrayLen(data)>
    <cfset data = data[1]>
</cfif>

接下来验证您现在正在使用包含预期键的结构。如果是这样,请继续进行常规处理。否则,会发生意外情况,代码应执行适当的错误处理。

<!--- Verify object is a structure and contains expected key(s) --->
<cfif IsStruct(data) && structKeyExists(data, "loginHosts")>
    ... process data as usual
<cfelse>
    ... data is not in expected format, do  error handling here
</cfif>

以上是一个非常 快速而粗糙的示例,但应该演示基本思想。只要您确定自己正确使用 API,您所能做的就是按照预期编写代码,并在发生不同情况时优雅地失败。