我有ColdFusion 9.0.1和最新的修补程序(4)。 我需要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。有什么想法吗?
这是一个简化的例子。我从数据库中获取这些数据。
答案 0 :(得分:6)
我知道这个问题已经很久了,但是作为一个新的CF开发人员,我也遇到了同样的问题,尽管我成功使用了上面的“字符串Hack”,但最终我从Cold Fusion文档中找到了一个更合适的解决方案{ {3}}。
'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序列化。
答案 1 :(得分:5)
这是一个解决方案 - 虽然是一个非常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);
答案 2 :(得分:1)
如果您有一个变量数组希望将其视为字符串(例如邮政跟踪号“ 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>
答案 3 :(得分:0)
只需在数字的开头添加一个简单的空格即可。 我最后尝试过这样做,但它不起作用。
<cfset test = StructNew()>
<cfset test.name = " 1234.100">
<cfoutput>#SerializeJSON(test)#</cfoutput>
输出
{"name":" 1234.100"}
答案 4 :(得分:0)
如果您不想使用kludge,可以使用正确编码JSON的第三方库。我使用了来自http://jsonutil.riaforge.org/的JSONUtil。我正在使用ColdFusion 9,所以我不知道更新版本的ColdFusion是否修复了一些编码异常。