Returning NULL Values In JSON Using SerializeJSON() And ColdFusion

Posted April 5, 2011 at 9:29 AM by Ben Nadel

Tags: ColdFusion

As I've been setting up a JSON-RPC (Remote Procedure Call) API for a ColdFusion project, I've been learning a few little tips and trips about JSON formation. Last week, I talked about how struct keys defined using array-notation maintain case during serialization. This week, in accordance with the JSON-RPC spec, I learned that you can return NULL JSON values by storing NULL ColdFusion values.

To demonstrate, I've mocked up an incomplete JSON-RPC example. According to the JSON-RPC specifications, a properly formed response cannot contain both an Error and a Result value at the same time; one of them must always be null. In order to ensure that a true JSON-null is returned, you have to store a null value in your ColdFusion response struct.

  • <!---
  • Define our basic JSON-RPC response structure. Note that we
  • are using array-notation in order to maintain case in the
  • serialization process.
  • --->
  • <cfset response = {} />
  • <cfset response[ "jsonrpc" ] = 2.0 />
  • <cfset response[ "result" ] = "Blam!" />
  • <cfset response[ "error" ] = {} />
  •  
  •  
  • <!---
  • For JSON-RPC, we cannot return both a RESULT and an ERROR in
  • same response. One of them has to be null. In order to return a
  • null value in the a JSON-serialization, we need to actually store
  • a NULL value in the ColdFusion struct.
  • --->
  • <cfset response.error = javaCast( "null", "" ) />
  •  
  •  
  • <!--- Serialize the JSON-RPC response. --->
  • <cfset serializedResponse = serializeJSON( response ) />
  •  
  • <!---
  • Stream the JSON response back to the client.
  •  
  • NOTE: The Mime-Type that we are using here is plain text only for
  • debugging purposes. In a real-world situation, you'd be returning
  • the JSON as application/json.
  • --->
  • <cfcontent
  • type="text/plain"
  • variable="#toBinary( toBase64( serializedResponse ) )#"
  • />

As you can see above, we are using javaCast() to store our null ColdFusion value. Doing so essentially destroys the usability of the key from a ColdFusion standpoint; but, from a JSON serialization standpoint, it's just what the doctor ordered. Running the above code gives us the following JSON response:

{ "jsonrpc":2.0, "error":null, "result":"Blam!" }

As you can see, the "error" key contains a true null value.

While this isn't the point of the post in any way, I should also mentioned that if you use ColdFusion to deserialize a JSON string that contains a null value, ColdFusion converts it into the string, "null". As such, if you're setting up a JSON-RPC API, you'll probably end up having to use a combination of structKeyExists() and (neq "null") statements.

Going from a typeless, case-insensitive language like ColdFusion to a format like JSON can prove to be a bit tricky at times; but, other than a few irksome numeric-conversions, ColdFusion tends to handle it surprisingly well - as long as you know how to work the system.




Reader Comments

Apr 5, 2011 at 10:49 AM // reply »
54 Comments

I have a strong emotional response to JSON-RPC. We internally have a server API that requires requests made in JSON and returns JSON responses. Getting back JSON responses is quite normal, and many interfaces implement this without calling themselves 'JSON-RPC'.

The significant issue is making requests in JSON. You must serialize the request with JSON.stringify (not avaiable in <IE8) and is not backwards compatible with HTML forms. If you are using jQuery, it will try to URLEncode your JSON object and seems to like to do the same to stringified JSON, so I also have to set processData false. I've ended up making a whole API to handle all of this in order to make even basic requests to the server.

So I beg you, change the name!


Apr 5, 2011 at 10:56 AM // reply »
10,743 Comments

@Drew,

For this project we're actually integrating with a 3rd party system that will be posting to our API. I am not even sure if JSON-RPC is easily doable with an AJAX-style approach. You can probably manually finagle the way data is sent; but in our case, the JSON value actually has to be posted as the request body (ie. getHTTPRequestData().content).

Honestly, I'm not crazy about the JSON-RPC specs; as you are saying, there's all kinds of complications when it comes to dealing with the browser. I'm only using it because it's pre-established in our integration spec.

At the end of the day, I'd rather just supply a standard URL interaction and then just have a normalized response structure. This spec seems to complicate my code somewhat :)


Apr 5, 2011 at 11:03 AM // reply »
54 Comments

@Ben,

It is further complicated in the case where you need to push things through a proxy. For instance, the curl module in PHP does not support JSON. I am currently using Apache mod proxy for testing, and still unsure what to use in production hopefully Ruby can provide a cross platform/http-server solution.


Apr 5, 2011 at 11:07 AM // reply »
10,743 Comments

@Drew,

Oh yeah - when you need to deal with really HTTP data, proxies always complicate the matter!


Apr 5, 2011 at 2:14 PM // reply »
38 Comments

@Drew Wells, so any problem with using jQuery with processData:false?


Apr 5, 2011 at 2:16 PM // reply »
54 Comments

@Henry,

Nope, I was lucky to find it, otherwise jQuery tries to serialize your data for you. I had the unfortunate experience of debugging this while using a proxy, so after many hours of Wireshark I discovered the issue.


Apr 5, 2011 at 5:01 PM // reply »
3 Comments

If you DeserializeJSON { "jsonrpc":2.0, "error":null, "result":"Blam!" }, you will not get back the original NULL value because ColdFusion9 cannot understand it.

On the other hand, if you ever use Railo 3.2, the result is even more interesting. When Railo encounter a null value, the struct key (in this case, "error") will be lost.

See my post regarding to DeserializeJSON() with the Railo team:

https://issues.jboss.org/browse/RAILO-1117


Apr 5, 2011 at 7:26 PM // reply »
10,743 Comments

@Peter,

Hmm, looks like Railo is using the same "null query value" approach where null values become empty strings. Ultimately, I am not sure what the best solution is. Since we are talking between two systems, it definitely gets tricky!!


Apr 5, 2011 at 11:22 PM // reply »
10 Comments

I've had good luck using Jackson for serializing/deserializing JSON with CF. It won't map to CFC instances, but it can handle nulls. It can work from cfmx-9, is very fast, and can be made to send integers as integers rather than floats.


Apr 6, 2011 at 7:09 AM // reply »
1 Comments

Lots of great information and inspiration, which we all need! I really appreciate the efforts made by you for this. Well Done! Thanks for sharing the information with us.


Apr 6, 2011 at 8:45 AM // reply »
10,743 Comments

@Mark,

Looks interesting (I just Googled "Jackson JSON" and I assume I found the right thing). Do you have problems with it converting strings to numbers? That's one of the biggest issues with CF-native JSON conversions that I see.

@Rupali,

Glad you find this helpful :)


Apr 6, 2011 at 4:46 PM // reply »
10 Comments

@Ben
It depends on where the data you're serializing comes from. You might have to do a lot of javaCast()'s. You also have to watch out for CF converting all your struct keys to uppercase, unless you use array notation (since JSON is case sensitive). However, something like a cfquery (if comes from jdbc, not queryNew()) -- the data is already of the right type.


Apr 7, 2011 at 10:25 PM // reply »
10,743 Comments

@Mark,

Thanks for the update. So far, the CF stuff hasn't been causing too much of an issue. But, we did just launch a beta API to the client application this afternoon. Soon, we'll see if "2" getting converted to 2.0 in the JSON will cause any type-mismatch errors (fingers crossed).



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 21, 2012 at 1:58 AM
Updated: Converting A ColdFusion Query To CSV Using QueryToCSV()
Hi Ben, why do you need to have so many double quotes when adding the field and field name to the row data? ----------------------------------------- <cfset LOCAL.RowData[ LOCAL.ColumnIndex ] = ... read »
AXL
May 21, 2012 at 1:24 AM
URL Rewriting And ColdFusion's WriteToBrowser Image Functionality (CFFileServlet)
@Mounir, Open your lower case URL Rewrite rule and add the following condition. Condition input: {REQUEST_URI} Check if input string: Does Not Match the Pattern Pattern: ^/CFFileServlet/_cf_ca ... read »
May 20, 2012 at 4:28 AM
Understanding The Complex And Circular Relationships Between Objects In JavaScript
@Will Vaughn I tried your javascript example but got this error:- foo.print is not a function ... read »
May 19, 2012 at 5:37 AM
A Graphical Explanation Of Javascript Closures In A jQuery Context
Thanks for this article, but I fear you missed an important point. If variables in the outer context change, these changes affect the inner anonymous functions as well. That means: if you change the ... read »
May 18, 2012 at 3:39 PM
Parsing CSV Data With An Input Stream And A Finite State Machine
Can you use file upload button with this? and read live? or does the file have to already be on the server saved? ... read »
May 18, 2012 at 1:06 AM
VIRGO (Aug. 23-Sept. 22): Dead On The Money!
A friend of mine and I were arguing about astrology and she told me that he believes in astrology. She hasn't provided me with any evidence that the belief makes any sense to me. She she been telling ... read »
May 17, 2012 at 11:32 PM
Using ColdFusion to Handle 404 Errors (Page Not Found) On Development Server
Very easy the configuration. I read a lot pages and I can't find the solution. I open the administrator and change this Administrator/server settings/Error Handlers/Missing Template Handler and p ... read »
May 17, 2012 at 3:13 PM
LOCAL Variables Scope Conflicts With ColdFusion Query of Queries
I never cease to be amazed that almost EVERY random CF issue I come across lands me on your site. Thank you for documenting your findings for the world. ... read »