Как разобрать ответ JSON и вставить в запрос

У меня есть следующий ответ 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."
}

Я использую функцию jsondecode из cflib для декодирования ответа 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, как вложить внутренние?

Снимок экрана


person Community    schedule 23.08.2015    source источник
comment
какую версию ColdFusion вы используете? К вашему сведению, есть встроенная функция DeserializeJSON()   -  person Henry    schedule 23.08.2015
comment
я на coldfusion 11   -  person    schedule 23.08.2015
comment
удалите код jsonencode и опубликуйте то, что вы уже пробовали.   -  person Henry    schedule 23.08.2015
comment
вставьте это в запрос coldfusion Чтобы уточнить, вы имеете в виду, что вам нужно вставить результаты в таблицу базы данных?   -  person Leigh    schedule 23.08.2015
comment
да @leigh, больше значений, которые должны быть в БД, - это структуры, начинающиеся с 0,1 и так далее   -  person    schedule 23.08.2015
comment
Содержит ли ответ поле с указанием общего числа? Похоже, он содержится в сообщении, т.е. Кампания из 4 номеров отправлена ​​успешно. но... есть ли отдельный общий ключ? Если нет, взгляните на комментарии под ответом Генри.   -  person Leigh    schedule 23.08.2015


Ответы (2)


JSON/CFML – цикл по массиву структур

Я спрашивал что-то подобное недавно.

Похоже, у вас есть массив структур. Вы можете десериализовать 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}
person TRose    schedule 23.08.2015

  1. используйте DeserializeJSON() для преобразования в структуру result.
  2. цикл через result.data с <cfloop>
  3. используйте <cfquery> для создания инструкции SQL INSERT, передайте значения с помощью <cfqueryparam>

Документ по ColdFusion: https://wikidocs.adobe.com/wiki/display/coldfusionen/Home< /а>

person Henry    schedule 23.08.2015
comment
result.data содержит разные элементы. Я вижу group_id и вижу 0 и 1. Зацикливание - это решение, но не тривиальное. Цикл от 1 до 100 проверяет, существует ли элемент. элемент цикла и проверить, является ли это числом, являются возможными решениями. - person Bernhard Döbler; 23.08.2015
comment
Странно, что в ответе не указано общее количество элементов через какой-то ключ. Если это так, другой возможностью является использование structCount. Предполагая, что data всегда содержит group_id плюс элементы с 1 по N, вы можете рассчитать количество элементов как structCount(result.data)-1. Затем выполните цикл от 1 до structCount(result.data)-1. Хотя, как упоминалось в @Bardware, обязательно сначала проверьте, существует ли каждый ключ. - person Leigh; 23.08.2015
comment
вот где он запутался, возвращенный json ответ совсем другой, и DeserializeJSON он не вернул ожидаемых результатов, поэтому пример такого рода, как его написать, очень поможет - person ; 23.08.2015
comment
@Darek - эта функция предназначена для того, чтобы делать противоположное тому, что вам нужно. Он создает json string. У вас уже есть строка. Вам нужно декодировать его в объекты CF, чтобы вы могли перебирать их в цикле - что и делает DeserializeJSON. Используя комментарии выше, можете ли вы показать нам, что вы уже пробовали? - person Leigh; 23.08.2015