If you have an array of variables that you want to be treated as strings (such as a postal tracking numbers "9449311899561067336896") you may run into an issue where ColdFusion thinks the strings look like numbers. ColdFusion may then try to convert the strings to integers, but if they are too long for an integer, an error may result. This could happen when the strings originated from an Array inside of Deserialized JSON.
You may think you could use the strings like this:
<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>
But it will result in an error such as Cannot convert the value 9.449311899561067E21 to an integer because it cannot fit inside an integer.
Instead you can use cfscript and 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>
The trackIdXml
variable was created inside of the cfscript tags, but can still be used like other Coldfusion variables, for example in a cfreturn <cfreturn #trackIdXml# />
Here is a full real-world example that requires integer-like strings to be kept as strings. This is a function that accepts an Array of USPS tracking numbers, and returns the package status response from the USPS's 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>