(слишком долго для комментариев)
мой код производит правильный результат является deserializeJSON(), что вызывает проблему.
Не совсем. Значение JSON верное, но сериализация не содержит окружающих котировок. Это означает, что значение будет обрабатываться как числовой тип во время десериализации, что вызовет проблему, которую вы наблюдаете.Если вы не можете принудительно выполнить сериализацию для обработки значения как строки, десериализованный результат всегда будет неправильным. Как Carl Von Stetten already mentioned, это ошибка. Ответ Jedihomer Townend appending a space character, вероятно, является самым простым обходом.
Более длинный ответ:
Несмотря на улучшение обработки JSON CF11, в CF еще немного слишком «полезно» ... Как вы отметили, CF определяет значение числовой при сериализации и опускает окружающие кавычки , Следовательно, обозначение типа значения как числовое.
Это звучит здорово, пока вы не попытаетесь десериализовать. Если значение было заключено в кавычки, оно будет обрабатываться как строка, а исходное значение будет сохранено. К сожалению, без кавычек считается числовыми, что означает CF должны набивать значение в one of its two numeric data types:
- Real или число с плавающей точкой, т.е.
java.lang.Double
или
- 32-битное целое, т.е.
java.lang.Integer
maximum value of an Integer - 2147483647. Очевидно, ваш номер слишком большой для этого, поэтому CF конвертирует его в java.lang.Double. Это проблема по двум причинам. Во-первых, Double - это approximate type. Во-вторых, согласно правилам этого класса, scientific notation may be used when representing the number as a String, т.е. когда переменная отображается с помощью cfoutput или cfdump. Вот почему десериализованный результат выглядит иначе, чем ожидалось. Если вы не можете заставить его обрабатывать строку при сериализации, результат десериализации всегда будет неправильным.
Справедливости ради, CF11 содержит ряд улучшений для обработки JSON. К сожалению, большинство из них вращаются вокруг объектов cfc и query. Учитывая вашу текущую структуру, она не будет довольно работы. Однако, если вы смогли использовать объект запроса , вы можете решить проблему с помощью нового уровня приложения this.serialization.serializeQueryAs = "struct";
. Это заставляет более разумный формат для сериализованных запросов, чем в более ранних версиях. Поскольку CF11 относится к типам данных столбцов при сериализации, значение сохраняется, если тип данных столбца BIGDECIMAL, или вы передаете его как VARCHAR. К сожалению, CF все еще содержит имена столбцов запроса, но базовые значения сохраняются.
Результат:
[ { "BUSINESSUNITVALIDLIST" : "2003051509034372557922",
"LONGMESSAGE" : "Request Completed Successfully.",
"SHORTMESSAGE" : "Success",
"STATUS" : 20001
} ]
Код:
qry = queryNew("");
queryAddColumn(qry, "businessUnitValidList", "varchar", ["2003051509034372557922"]);
queryAddColumn(qry, "shortMessage", "varchar", ["Success"]);
queryAddColumn(qry, "longMessage", "varchar", ["Request Completed Successfully."]);
queryAddColumn(qry, "status", "integer", [20001]);
json = serializeJSON(qry);
writeDump(deserializeJSON(json));
CF11 также введены пользовательские сериализаторы/deserializers, которые мощь работа здесь. Хотя это, вероятно, слишком велико для этой конкретной задачи.
Сказав все это, простейшим вариантом является использование «добавления нечислового символа». Что ж ..Либо так, либо перейти в пользовательскую библиотеку, которая может сделать более последовательную работу с обработкой JSON ;-)
Side Примечание/Эффективность:
Если нет особых причин, вы должны выполнить запрос в в цикле есть более эффективные варианты (специфичные для dbms, о которых вы не упомянули). Кроме того, не забудьте использовать cfqueryparam
для всех переменных параметров запроса. Среди многих преимуществ - повышение производительности, когда один и тот же запрос выполняется несколько раз - например, внутри цикла.
Как мы должны помочь вам, если вы не предоставили код, который имеет эту проблему? Вы были здесь достаточно долго, чтобы знать, как задавать соответствующие вопросы - [mcve] –
Попробуйте преобразовать его в строку и включить ведущее пространство; например «businessUnitValidList»: «2003051509034372557922» –
Вы также можете попробовать использовать функцию 'PrecisionEvaluate()' на нем - http://stackoverflow.com/a/16968077/1636917 –