17

我有带有最新修补程序 (4) 的 ColdFusion 9.0.1。我需要 ColdFusion 返回所有带有引号的 JSON 数据(作为字符串)。我有以下问题:

<cfset test = StructNew()>
<cfset test.name = "1234.100">
<cfoutput>#SerializeJSON(test)#</cfoutput>

输出的文本是:

{"name":1234.100}

每个 javascript JSON 解析器都将其转换为 1234.1,并且不保留尾随的 0。我要么需要 ColdFusion 以字符串形式输出,要么需要 javascript 解析器来保留尾随的 0。有任何想法吗?

这是一个简化的例子。我正在从数据库中获取这些数据。

4

5 回答 5

14

我知道这个问题很老,但是作为一个新的 CF 开发人员,我遇到了同样的问题,虽然我成功地使用了上面的“字符串 Hack”,但最后我从 Cold Fusion 文档中找到了一个更适合serializeJSON的解决方案。

'Adobe ColdFusion(2016 版)更新 2 使您能够为结构中的键指定数据类型信息。这被称为元数据。

<cfscript>
   example = structnew();
   example.firstname = "Yes";
   example.lastname = "Man";
   writeoutput("<b>After serialization</b>:");
   // change the JSON key firstname to fname 
   metadata = {firstname: {type:"string",name:"fname"}};
   example.setMetadata(metadata);
   writeoutput(SerializeJSON(example));
</cfscript>

虽然该示例显示了修改字符串“Yes”的元数据以保持字符串,而不是转换为布尔值,但它同样适用于将数字转换为字符串以进行 JSON 序列化。

于 2018-08-07T13:29:06.683 回答
8

这是一个解决方案 - 虽然是一个非常hacky,不雅的解决方案......

您的设置:

var test = {
  name = "1234.100"
};

在前面添加一些明显的字符串会强制该值在转换为 JSON 时变为字符串。然后我们摆脱这个丑陋的字符串。

var thisIsSuchAHorribleHack = "(!@$!@$)";
test.name = thisIsSuchAHorribleHack & test.name;
var serializedTest = SerializeJSON(test);
serializedTest = Replace(serializedTest, thisIsSuchAHorribleHack, "", "ALL");
writeOutput(serializedTest);
于 2014-04-02T19:24:22.213 回答
2

如果您有一组变量希望被视为字符串(例如邮政追踪号码“9449311899561067336896”),您可能会遇到 ColdFusion 认为字符串看起来像数字的问题。ColdFusion 可能会尝试将字符串转换为整数,但如果它们对于整数来说太长,则可能会导致错误。当字符串源自反序列化 JSON 中的数组时,可能会发生这种情况。

你可能认为你可以使用这样的字符串:

<cfset trackIdXml = "" />   
<!--- Loop through all tracking numbers and build the XML --->
<cfloop array="#trackingNumsArray#" index="i">          
    <cfset trackIdXml &= "<TrackID ID=""" />
    <cfset trackIdXml &= #trackingNumsArray[i]# />
    <cfset trackIdXml &= """/>" />
</cfloop>

但这会导致错误,例如Cannot convert the value 9.449311899561067E21 to an integer because it cannot fit inside an integer.

相反,您可以使用 cfscript 和java.lang.StringBuffer

<cfscript>
    //This variable will store the XML that is used in the API request to list each tracking number
    //We must tell ColdFusion that this is a string buffer, and use .append(). Why?
    //ColdFusion will try to convert the tracking number to a integer if we do not explicitly tell it
    //to treat it as a string.
    trackIdXml = createObject("java",  "java.lang.StringBuffer").init();

    for (trackingNum in trackingNumsArray) {
        trackIdXml.append('<TrackID ID="');
        trackIdXml.append(#trackingNum#);
        trackIdXml.append('"/>');
    }
</cfscript>

trackIdXml变量是在 cfscript 标记内创建的,但仍可以像其他 Coldfusion 变量一样使用,例如在 cfreturn<cfreturn #trackIdXml# />

这是一个完整的真实示例,需要将类似整数的字符串保存为字符串。这是一个接受 USPS 跟踪号码数组的函数,并从 USPS 的 API 返回包裹状态响应:

<cfcomponent>
    <cffunction name="uspsLookup" access="remote" returntype="string" returnformat="plain" output="yes">
        <cfargument name="trackingNums" type="string" required="yes" />
        <cfset trackingNumsArray = DeserializeJSON(trackingNums, true) />

        <cfscript>
            trackIdXml = createObject("java",  "java.lang.StringBuffer").init();

            for (trackingNum in trackingNumsArray) {
                trackIdXml.append('<TrackID ID="');
                trackIdXml.append(#trackingNum#);
                trackIdXml.append('"/>');
            }
        </cfscript>
        
        <cfset userid = "XXXXXXXXXXXX" />
        
        <cfhttp
        method="GET"
        url='http://production.shippingapis.com/ShippingAPI.dll?API=TrackV2&XML=<TrackRequest USERID="#userid#">#trackIdXml#</TrackRequest>'>
        </cfhttp>
        
        <cfif #cfhttp.Statuscode# IS "200 OK" >
            <cfreturn "#cfhttp.Filecontent#">
        <cfelse>
            <cfreturn "error||#cfhttp.Statuscode#">
        </cfif>  
    </cffunction>
</cfcomponent>
于 2020-08-05T15:40:28.307 回答
1

如果您不想使用 kludge,可以使用正确编码 JSON 的第三方库。我使用了来自http://jsonutil.riaforge.org/的JSONUtil 。我正在使用 ColdFusion 9,所以我不知道最新版本的 ColdFusion 是否修复了一些编码异常。

于 2015-02-27T16:07:31.167 回答
1

只需在号码的开头添加一个简单的空格即可。我尝试在最后这样做,但它不起作用。

<cfset test = StructNew()>
<cfset test.name = " 1234.100">
<cfoutput>#SerializeJSON(test)#</cfoutput>

输出将是

{"name":" 1234.100"}
于 2015-02-26T12:49:55.913 回答