【问题标题】:How to parse JSON response and insert into Query如何解析 JSON 响应并插入查询
【发布时间】:2015-08-24 03:40:41
【问题描述】:

我有以下 JSON 响应,我真的不知道如何使用循环将它插入到 ColdFusion 查询中。

回复是这样的:

 {  
   "status":"OK",
   "data":{  
      "group_id":1522413460,
      "0":{  
         "id":"1522413460-1",
         "customid":"",
         "customid1":"",
         "customid2":"",
         "mobile":"0000000000",
         "status":"AWAITED-DLR"
      },
      "1":{  
         "id":"1522413460-2",
         "customid":null,
         "customid1":null,
         "customid2":null,
         "mobile":"0000000000",
         "status":"AWAITED-DLR"
      },
      "2":{  
         "id":"1522413460-3",
         "customid":null,
         "customid1":null,
         "customid2":null,
         "mobile":"0000000000",
         "status":"AWAITED-DLR"
      },
      "3":{  
         "id":"1522413460-4",
         "customid":null,
         "customid1":null,
         "customid2":null,
         "mobile":"",
         "status":"INV-NUMBER"
      }
   },
   "message":"Campaign of 4 numbers Submitted successfully."
}

我正在使用 cflib 中的 jsondecode 函数将 JSON 的响应解码为嵌套结构:

<cffunction name="jsonencode" access="remote" returntype="string" output="No" hint="Converts data from CF to JSON format">
    <cfargument name="data" type="any" required="Yes" />
    <cfargument name="queryFormat" type="string" required="No" default="query" /> <!-- query or array -->
    <cfargument name="queryKeyCase" type="string" required="No" default="lower" /> <!-- lower or upper -->
    <cfargument name="stringNumbers" type="boolean" required="No" default=false >
    <cfargument name="formatDates" type="boolean" required="No" default=false >
    <cfargument name="columnListFormat" type="string" required="No" default="string" > <!-- string or array -->
    <cfset var jsonString = "" />
    <cfset var tempVal = "" />
    <cfset var arKeys = "" />
    <cfset var colPos = 1 />
    <cfset var i = 1 />
    <cfset var column = ""/>
    <cfset var datakey = ""/>
    <cfset var recordcountkey = ""/>
    <cfset var columnlist = ""/>
    <cfset var columnlistkey = ""/>
    <cfset var dJSONString = "" />
    <cfset var escapeToVals = "\\,\"",\/,\b,\t,\n,\f,\r" />
    <cfset var escapeVals = "\,"",/,#Chr(8)#,#Chr(9)#,#Chr(10)#,#Chr(12)#,#Chr(13)#" />

    <cfset var _data = arguments.data />

    <!--- BOOLEAN --->
    <cfif IsBoolean(_data) AND NOT IsNumeric(_data) AND NOT ListFindNoCase("Yes,No", _data)>
        <cfreturn LCase(ToString(_data)) />

    <!--- NUMBER --->
    <cfelseif NOT stringNumbers AND IsNumeric(_data) AND NOT REFind("^0+[^\.]",_data)>
        <cfreturn ToString(_data) />

    <!--- DATE --->
    <cfelseif IsDate(_data) AND arguments.formatDates>
        <cfreturn '"#DateFormat(_data, "medium")# #TimeFormat(_data, "medium")#"' />

    <!--- STRING --->
    <cfelseif IsSimpleValue(_data)>
        <cfreturn '"' & ReplaceList(_data, escapeVals, escapeToVals) & '"' />

    <!--- ARRAY --->
    <cfelseif IsArray(_data)>
        <cfset dJSONString = createObject('java','java.lang.StringBuffer').init("") />
        <cfloop from="1" to="#ArrayLen(_data)#" index="i">
            <cfset tempVal = jsonencode( _data[i], arguments.queryFormat, arguments.queryKeyCase, arguments.stringNumbers, arguments.formatDates, arguments.columnListFormat ) />
            <cfif dJSONString.toString() EQ "">
                <cfset dJSONString.append(tempVal) />
            <cfelse>
                <cfset dJSONString.append("," & tempVal) />
            </cfif>
        </cfloop>

        <cfreturn "[" & dJSONString.toString() & "]" />

    <!--- STRUCT --->
    <cfelseif IsStruct(_data)>
        <cfset dJSONString = createObject('java','java.lang.StringBuffer').init("") />
        <cfset arKeys = StructKeyArray(_data) />
        <cfloop from="1" to="#ArrayLen(arKeys)#" index="i">
            <cfset tempVal = jsonencode( _data[ arKeys[i] ], arguments.queryFormat, arguments.queryKeyCase, arguments.stringNumbers, arguments.formatDates, arguments.columnListFormat ) />
            <cfif dJSONString.toString() EQ "">
                <cfset dJSONString.append('"' & arKeys[i] & '":' & tempVal) />
            <cfelse>
                <cfset dJSONString.append("," & '"' & arKeys[i] & '":' & tempVal) />
            </cfif>
        </cfloop>

        <cfreturn "{" & dJSONString.toString() & "}" />

    <!--- QUERY --->
    <cfelseif IsQuery(_data)>
        <cfset dJSONString = createObject('java','java.lang.StringBuffer').init("") />

        <!--- Add query meta data --->
        <cfif arguments.queryKeyCase EQ "lower">
            <cfset recordcountKey = "recordcount" />
            <cfset columnlistKey = "columnlist" />
            <cfset columnlist = LCase(_data.columnlist) />
            <cfset dataKey = "data" />
        <cfelse>
            <cfset recordcountKey = "RECORDCOUNT" />
            <cfset columnlistKey = "COLUMNLIST" />
            <cfset columnlist = _data.columnlist />
            <cfset dataKey = "data" />
        </cfif>

        <cfset dJSONString.append('"#recordcountKey#":' & _data.recordcount) />
        <cfif arguments.columnListFormat EQ "array">
            <cfset columnlist = "[" & ListQualify(columnlist, '"') & "]" />
            <cfset dJSONString.append(',"#columnlistKey#":' & columnlist) />
        <cfelse>
            <cfset dJSONString.append(',"#columnlistKey#":"' & columnlist & '"') />
        </cfif>
        <cfset dJSONString.append(',"#dataKey#":') />

        <!--- Make query a structure of arrays --->
        <cfif arguments.queryFormat EQ "query">
            <cfset dJSONString.append("{") />
            <cfset colPos = 1 />

            <cfloop list="#_data.columnlist#" delimiters="," index="column">
                <cfif colPos GT 1>
                    <cfset dJSONString.append(",") />
                </cfif>
                <cfif arguments.queryKeyCase EQ "lower">
                    <cfset column = LCase(column) />
                </cfif>
                <cfset dJSONString.append('"' & column & '":[') />

                <cfloop from="1" to="#_data.recordcount#" index="i">
                    <!--- Get cell value; recurse to get proper format depending on string/number/boolean data type --->
                    <cfset tempVal = jsonencode( _data[column][i], arguments.queryFormat, arguments.queryKeyCase, arguments.stringNumbers, arguments.formatDates, arguments.columnListFormat ) />

                    <cfif i GT 1>
                        <cfset dJSONString.append(",") />
                    </cfif>
                    <cfset dJSONString.append(tempVal) />
                </cfloop>

                <cfset dJSONString.append("]") />

                <cfset colPos = colPos + 1 />
            </cfloop>
            <cfset dJSONString.append("}") />
        <!--- Make query an array of structures --->
        <cfelse>
            <cfset dJSONString.append("[") />
            <cfloop query="_data">
                <cfif CurrentRow GT 1>
                    <cfset dJSONString.append(",") />
                </cfif>
                <cfset dJSONString.append("{") />
                <cfset colPos = 1 />
                <cfloop list="#columnlist#" delimiters="," index="column">
                    <cfset tempVal = jsonencode( _data[column][CurrentRow], arguments.queryFormat, arguments.queryKeyCase, arguments.stringNumbers, arguments.formatDates, arguments.columnListFormat ) />

                    <cfif colPos GT 1>
                        <cfset dJSONString.append(",") />
                    </cfif>

                    <cfif arguments.queryKeyCase EQ "lower">
                        <cfset column = LCase(column) />
                    </cfif>
                    <cfset dJSONString.append('"' & column & '":' & tempVal) />

                    <cfset colPos = colPos + 1 />
                </cfloop>
                <cfset dJSONString.append("}") />
            </cfloop>
            <cfset dJSONString.append("]") />
        </cfif>

        <!--- Wrap all query data into an object --->
        <cfreturn "{" & dJSONString.toString() & "}" />

    <!--- UNKNOWN OBJECT TYPE --->
    <cfelse>
        <cfreturn '"' & "unknown-obj" & '"' />
    </cfif>
</cffunction>

更新 #1: 使用 DeserializeJSON,我得到以下屏幕截图。如果我遍历名为 data 的结果,如何嵌套内部的结果?

【问题讨论】:

  • 您使用的是什么版本的 ColdFusion?仅供参考,有一个内置的 DeserializeJSON() 函数
  • 我正在使用coldfusion 11
  • 删除 jsonencode 代码,并发布您迄今为止尝试过的内容。
  • 在coldfusion查询中插入为了澄清,你的意思是你需要将结果插入到数据库表中吗?
  • 是的@leigh,更多需要在 DB 中的值是以 0,1 等开头的结构体

标签: json coldfusion coldfusion-11


【解决方案1】:

JSON / CFML - Looping over an array of structs

我最近问过类似的问题。

看起来你有一个结构数组。您可以像其他人描述的那样反序列化 JSON,并按照我的链接所示循环遍历它。

为清楚起见进行编辑

这是对我有用的代码。由于您收到的响应似乎不包含编码字符,因此我已经删除了一个步骤。

<cfset requestBody = #(toString(getHttpRequestData().content)/>
<cfset ArrayOfStructs = deserializeJson(requestBody)>
<cfloop array="#ArrayOfStructs#" index="i">
<cfquery name="doodoodoo" datasource="CRM">
    INSERT INTO TimeAppTest
    (
        EmployeeID,
        lat,
        long,
        TimoStampo
        )
    VALUES
    (
        '#i.barcode#',
        '#i.lat#',
        '#i.long#',
        '#i.time#'

        )
</cfquery>
</cfloop>

JSON 就是这样,解释不同的变量名称。

{"barcode":"CSS1035","scannerID":"3e81b04aa521a05e","time":"2015-08-11 08:30:27.232","lat":32.4001579,"long":-110.0403455},
{"barcode":"CSS1959","scannerID":"3e81b04aa521a05e","time":"2015-08-11 08:30:29.366","lat":32.4001579,"long":-110.0403455},
{"barcode":"CSS1649","scannerID":"3e81b04aa521a05e","time":"2015-08-11 08:30:31.642","lat":32.4001579,"long":-110.0403455}

【讨论】:

    【解决方案2】:
    1. 使用DeserializeJSON() 转换为结构result
    2. 循环通过result.data&lt;cfloop&gt;
    3. 使用&lt;cfquery&gt;构造SQL INSERT语句,通过&lt;cfqueryparam&gt;传值

    ColdFusion 文档: https://wikidocs.adobe.com/wiki/display/coldfusionen/Home

    【讨论】:

    • result.data 似乎包含不同的项目。我看到了group_id,我看到了01。循环是解决方案,但并非微不足道。如果项目存在,则从 1 到 100 循环测试。循环项目并测试它是否是一个数字是可能的解决方案。
    • 奇怪的是响应没有通过某种键指示元素的总数。如果是这样,另一种可能性是使用 structCount。假设data 始终包含group_id 加上项目1 到N,您可以计算项目数为structCount(result.data)-1。然后从 1 循环到 structCount(result.data)-1。尽管正如@Bardware 提到的,请务必先测试每个键是否存在。
    • 这是混淆的地方,返回的json 响应完全不同,DeserializeJSON 它没有返回预期的结果,所以这种如何实际编写它的示例,将有助于很多
    • @Darek - 该功能旨在与您的需求相反。它创建一个 json 字符串。你已经有一个字符串。您需要将其解码为 CF 对象,以便循环访问它们 - 这就是 DeserializeJSON 所做的。使用上面的 cmets - 你能告诉我们你到目前为止尝试了什么吗?
    猜你喜欢
    • 1970-01-01
    • 2015-12-28
    • 2012-03-27
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    相关资源
    最近更新 更多