使用ColdFusion附加到JSON数组,考虑Null值? [英] Append to JSON array with ColdFusion, taking Null values into consideration?

查看:158
本文介绍了使用ColdFusion附加到JSON数组,考虑Null值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在这里挖了一段时间,但我不相信我的大脑是如何做到这一点的提示。



我需要这个JSON:

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

看起来像这样JSON:

 '{loginHosts:[server1.example.com,server2.example.com,newserver1.example.com,newserver2.example.com] ,sudoHosts:[server1.example.com,server2.example.com,newserver1.example.com,newserver2.example.com],CPG:my_group :test@example.com,loginShell:/ bin / bash}'

有一些注意事项。


  1. 我要求的JSON应用程序需要返回这些字段,无论是否为null:loginHosts,sudoHosts,CPG, mail,loginShell。


  2. JSON应用程序期望loginHosts,sudoHosts和CPG作为数组[]返回,即使为null。 IE:'{loginHosts:[],sudoHosts:[]}'


  3. 原始的loginHosts和sudoHosts数据(如:server1.example .com,server2.example.com)必须保留在发送回应用程序的JSON字符串中。


  4. 很多时候,loginHosts和sudoHosts会作为Null数组发送到我的应用程序。 IE:'{loginHosts:[],sudoHosts:[]}'


在运行Lucee 4.5和Linux操作系统的服务器上。获取/设置JSON字符串;我使用CFEXECUTE ssh到远程Linux服务器来拉/推我的JSON字符串。您可以在这里看到原因:通过ColdFusion(Lucee)填充大型JSON数据集的SELECT非常慢



我到目前为止的代码是:

 < cfset user_list ='{loginHosts:[server1.example.com,server2.example.com],sudoHosts:[ server1.example.com,server2.example.com],CPG:my_group,mail:test@example.com,loginShell:/ bin / bash}'

< cfset arrayOfStructs = deserializeJson(user_list)>

< cfloop array =#arrayOfStructs#index =user>
< cfif structKeyExists(user,loginHosts)>
< cfloop array =#user.loginHosts#index =login>
< cfset loginHosts =#login#>
< / cfif>
< cfif structKeyExists(user,sudoHosts)>
< cfloop array =#user.sudoHosts#index =hosts>
< cfset sudoHosts =#hosts#>
< / cfif>
< cfif structKeyExists(user,CPG)>
< cfloop array =#user.CPG#index =cp>
< cfset CPG =#cp#>
< / cfif>
< cfset mail =#user.mail#>
< cfset loginShell =#user.loginShell#>
< / cfloop>
< cfset my_servers =newserver1.example.com,newserver2.example.com>
< cfset loginHosts = listAppend(loginHosts,#my_servers#,,)>
< cfset myStruct ='{loginHosts:[#loginHosts#],sudoHosts:[#sudoHosts#],CPG:[#cp#] :#mail#,loginShell:#loginShell#}'/>

然后myStruct被序列化,并使用前面提到的CFEXECUTE方法发送回远程服务器。 / p>

代码工作有点儿但是有两件事情不工作。首先,每个cfset loginHosts和cfset sudoHosts仅返回JSON(server2.example.com)中的第二个服务器。我知道我正在覆盖我自己的loginHosts在CFLOOP,但我不知道如何纠正,并检查loginHosts数组是否为空。



我也有保留双引号的问题,以便它们保留在JSON中。在我的测试中,我得到这个:

  [server1.example.com,server2.example.com,newserver1 .example.com,newserver2.example.com] 

请注意,newserver1和newserver2?



我试过在我的listAppend()中添加转义的引号:#my_servers。它似乎工作正常,直到我有JSON字符串中返回的Null值。



任何向正确的方向微移将是赞赏!



EDIT ---



一些澄清:



为什么:以向数据库添加其他服务器名称。要使用该数据库,我需要使用发送JSON并期望返回JSON的API。这必须通过使用curl的BASH shell脚本来完成。正如我上面发布的,这是原因:通过ColdFusion(Lucee)填充大JSON数据集的SELECT非常慢



我在应用程序中使用了serializeJSON()和deserializeJSON 。我的代码顶部的user_list只是为了告诉你我使用什么数据。它不是手写的。



编辑2 -





底部的myStruct填充了arrayOfStructs的数据,然后序列化。

 < cfset myJsonvar = serializeJSON(myStruct)/> 

然后使用CFEXECUTE通过SSH将'myJsonvar'作为字符串发送到BASH脚本然后使用curl提交数据。是的,复杂,但它的我的安全。

解决方案

我会简化的代码相当多。看起来好像你正在做的是将两个新的服务器添加到struct中的一个现有的loginHosts列表中;不需要任何循环。

 < cfset user_list ='{loginHosts:[server1.example.com ,server2.example.com],sudoHosts:[server1.example.com,server2.example.com],CPG:my_group,mail:test @ example。 com,loginShell:/ bin / bash}'> 

< cfset myStruct = deserializeJson(user_list)>

< cfset myServers = [newserver1.example.com,newserver2.example.com]>

<!---如果loginHosts不是一个数组,使它成为一个数组。 --->
< cfif NOT structKeyExists(myStruct,'loginHosts')或NOT isArray(myStruct.loginHosts)>
< cfset myStruct.loginHosts = []>
< / cfif>
< cfset arrayAppend(myStruct.loginHosts,myServers,true)>

< cfset user_list = serializeJSON(myStruct)>
<!--- now user_list是一个json字符串,将新服务器添加为登录主机,其余结构保持不变。 --->


I have been digging here on Stack for some time but I do not believe my brain is getting the hint on how to do this.

I need this JSON:

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

To look like this JSON:

'{"loginHosts":["server1.example.com","server2.example.com","newserver1.example.com","newserver2.example.com"],"sudoHosts":["server1.example.com","server2.example.com","newserver1.example.com","newserver2.example.com"],"CPG":"my_group","mail":"test@example.com","loginShell":"/bin/bash"}'

There are some caveats.

  1. The JSON application I am pulling from, requires these fields be returned, whether null or not: loginHosts, sudoHosts, CPG, mail, loginShell. If they are not returned the application complains.

  2. The JSON application expects loginHosts, sudoHosts, and CPG to be returned as an array [] even if null. I.E.: '{"loginHosts":[],"sudoHosts":[]}'

  3. The original loginHosts and sudoHosts data (such as: server1.example.com, server2.example.com) must remain in the JSON string sent back to the application. So all of my new data must be appended.

  4. There are many times when loginHosts and sudoHosts are sent to my application as Null arrays. I.E.: '{"loginHosts":[],"sudoHosts":[]}'

I am developing this on a server running Lucee 4.5 with a Linux OS. To get/set the JSON string; I use CFEXECUTE to ssh to a remote Linux server to pull/push my JSON string. You can see the reason for that here: Populating SELECT with large JSON data set via ColdFusion (Lucee) very slow

The code I have so far:

    <cfset user_list = '{"loginHosts":["server1.example.com","server2.example.com"],"sudoHosts":["server1.example.com","server2.example.com"],"CPG":"my_group","mail":"test@example.com","loginShell":"/bin/bash"}'

<cfset arrayOfStructs = deserializeJson(user_list)>

<cfloop array="#arrayOfStructs#" index="user">
    <cfif structKeyExists(user, "loginHosts")>
        <cfloop array="#user.loginHosts#" index="login">
                <cfset loginHosts = #login#>
        </cfloop>
    </cfif>
    <cfif structKeyExists(user, "sudoHosts")>
        <cfloop array="#user.sudoHosts#" index="hosts">
            <cfset sudoHosts = #hosts#>
        </cfloop>
    </cfif>                             
    <cfif structKeyExists(user, "CPG")>
        <cfloop array="#user.CPG#" index="cp">
            <cfset CPG = #cp#>
        </cfloop>
    </cfif>
    <cfset mail = #user.mail#>
    <cfset loginShell = #user.loginShell#>
</cfloop>
<cfset my_servers = "newserver1.example.com,newserver2.example.com">
<cfset loginHosts = listAppend(loginHosts, "#my_servers#", ",")>
<cfset myStruct = '{"loginHosts":["#loginHosts#"],"sudoHosts":["#sudoHosts#"],"CPG":["#cp#"],"mail":"#mail#","loginShell":"#loginShell#"}'/>

The myStruct is then serialized and sent back to the remote server using the CFEXECUTE method I mentioned earlier.

That code works a little but two things are not working. First, each cfset loginHosts and cfset sudoHosts are only returning the second server in the JSON (server2.example.com). I understand that I am overwriting my own loginHosts in that CFLOOP but I am not sure how to correct that and also check if the loginHosts array is Null.

I am also having problems preserving double quotes so that they remain in the JSON. In my testing I get this:

["server1.example.com","server2.example.com","newserver1.example.com,newserver2.example.com"]

Notice the missing "," between newserver1 and newserver2?

I have tried adding escaped quotes to my listAppend() like this: """#my_servers""". It seems to work OK until I have a Null value returned in the JSON string.

Any nudge in the right direction would be appreciated!

EDIT ---

Some clarification:

Why: I am simply wanting to add additional server names to a database. To work with that database I am required to use an API that sends JSON and expects JSON back. This has to be done through a BASH shell script that utilizes curl. As I posted above, this is the reason: Populating SELECT with large JSON data set via ColdFusion (Lucee) very slow

I am using serializeJSON() and deserializeJSON() a lot in my application. The "user_list" at the top of my code is simply there to show you what data I am given to work with. It was not written by hand.

EDIT 2 --

My apologies for not adding this line to my code above.

The 'myStruct' at the bottom gets populated with the data from the "arrayOfStructs" and then serialized.

<cfset myJsonvar = serializeJSON(myStruct)/>

The 'myJsonvar' is then sent as a string, over SSH using CFEXECUTE, to a BASH script that then uses curl to submit the data. Yes, convoluted, but its what I have due to security.

解决方案

I would simplify the code quite a bit. It appears as though all you are doing is adding your two new servers to an existing list of loginHosts within your struct; that doesn't require any looping.

<cfset user_list = '{"loginHosts":["server1.example.com","server2.example.com"],"sudoHosts":["server1.example.com","server2.example.com"],"CPG":"my_group","mail":"test@example.com","loginShell":"/bin/bash"}'>

<cfset myStruct = deserializeJson(user_list)>

<cfset myServers = ["newserver1.example.com","newserver2.example.com"]>

<!--- if loginHosts isn't an array, make it one. --->
<cfif NOT structKeyExists(myStruct, 'loginHosts') OR NOT isArray(myStruct.loginHosts)> 
  <cfset myStruct.loginHosts = []>
</cfif>
<cfset arrayAppend(myStruct.loginHosts, myServers, true)>

<cfset user_list = serializeJSON(myStruct)>
<!--- now user_list is a json string with your new servers added as login hosts, the rest of the struct remains the same. --->

这篇关于使用ColdFusion附加到JSON数组,考虑Null值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆