KingErroneous
KingErroneous

Reputation: 989

Coldfusion JSON serialization inconsistency

I wrote the following component:

<cfcomponent>

<cffunction name="test" returntype="struct" access="remote" returnformat="json">
    <cfset local.str = structNew()>

    <cfset str.a = "hello">
    <cfset str.b = 23>

    <cfreturn local.str>
</cffunction>

</cfcomponent>

When I run this in my dev environment I get the following:

{"A":"hello","B":"23"}

In production, I get this:

{"A":"hello","B":23}

Same code, same CF version, same JVM, different results. Anybody know why?

Upvotes: 1

Views: 1800

Answers (4)

Mike Causer
Mike Causer

Reputation: 8314

Check this one out.

Any entirely numeric string with trailing D or F followed by whitespace.

<cfscript>
struct = { "wtf" = "4D " };
string = serializeJSON( struct );

string == {"wtf":4D }
</cfscript>

Try deserializing it.

<cfscript>
struct = deserializeJSON( '{"wtf":4D }' );
</cfscript>

JSON parsing failure at character 9:'D' in {"wtf":4D }

Umm what??

The parser trims and checks if the last character is D or F (double or float) and strips it. If the remaining characters are numeric, no quotes are added.

If you dont have trailing whitespace, it works perfectly. The specific combo of number, D|F and spaces trips it up.

(I've submitted it to Adobe cfbugs)

Upvotes: 0

Jake Feasel
Jake Feasel

Reputation: 16955

It appears that this is bug in CF9. Not sure how you are getting different results from your local / production version. See this blog post for a detailed discussion:

http://coldfusion.tcs.de/adobe-please-fix-coldfusion-serializejson/

It looks like you have four options.

  1. Modify your code to expect strings instead of numbers
  2. Roll back your CF server to 9.0
  3. Use Railo instead of Adobe CF
  4. Switch to a different JSON serializer. Apparently there are two named CFJSON: http://cfjson.riaforge.org/ and Dan Roberts' suggestion http://www.epiphantastic.com/cfjson/

Upvotes: 1

artlung
artlung

Reputation: 34003

If you set the members of the Struct using cfscript instead of cfset do you get a different result? e.g.:

<cfscript>
str.a = "hello";
str.b = 23;
</script>

You might also try your cfset as:

<cfset str.b = Int(23)>

I've not seen the behavior described, possibly one of these approaches will help.


Yet another casting approach. How about trying:

<cfset str.b = JavaCast("int", 23)>

Upvotes: 0

Dan Roberts
Dan Roberts

Reputation: 4694

I've noticed similar issues before but never paid attention to the exact results between machine/environments. Just seems like we are asking for trouble trying to convert a weakly typed language to a strongly typed language.

A few things to check

  1. Any differences in patch or hotfixes for the CF servers?

  2. Are your results consistent on every run or do they change occasionally even on the same machine? For example if you restart CF, change the file slightly (to force recompile) then run it multiple times are the results different on the first run than some later runs?

  3. Does anything change if you var scope local.str?

Another option to consider is using CFJSON, which I believe is much more consistent, to serialize then output the string. We use it our primary app (the current maintainer was actually a consultant that did some work for us).

Upvotes: 0

Related Questions