JSON output question

40 views
Skip to first unread message

Brian C

unread,
Dec 20, 2014, 9:41:56 AM12/20/14
to taffy...@googlegroups.com
I am using CFSAVECONTENT to build some JSON manually and put it in a variable called theResult.

The problem is that when I return it to the caller using representationOf, all of the double quotes get escaped again and all of the hard carriage returns get turned into \n\r.

I was about to override the serializer and simply cut out the serializeJSON but thinking that I must have missed something in the docs.

Is there an easier way to do this?

Thanks for the framework and any help.

Brian

Adam Tuttle

unread,
Dec 20, 2014, 9:49:56 AM12/20/14
to taffy...@googlegroups.com

If serializeJson isn't going to do the job correctly (the only reason I can imagine you'd be creating your json manually), then you probably want to implement a custom serializer. I'm on my phone or I'd give you some more information. There's a guide in the wiki on GitHub.

--
You received this message because you are subscribed to the Google Groups "Taffy Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to taffy-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brian C

unread,
Dec 20, 2014, 10:46:08 AM12/20/14
to taffy...@googlegroups.com
The JSON expected out of the API is predefined.

Using structs and arrays to build up a data structure and then allowing serializeJSON to output it, while convenient, produces several things I don't believe I can correct for.

For example I am trying to output:
{ "widgets": [
      {
         "id": 40252,
         "name": "Some name",
         "dueDate": "December, 31 2014 00:00:00"
      },
      {
         "id": 43212,
         "name": "Other name",
         "dueDate": "December, 22 2014 00:00:00"
      }
]}

But using structs and arrays I get this instead:

{
   "1": {
      "DUEDATE": "December, 31 2014 00:00:00",
      "ID": 40252,
      "NAME": "Some name"
   },
   "2": {
      "DUEDATE": "December, 22 2014 00:00:00",
      "ID": 43212,
      "NAME": "Other name"
   },
}

Seems like the best way to get the exact structure defined for the API is to hand-roll the JSON string.

Right?

I am working through the WiKi explanation for the custom serializer which should allow me to skip the extra serializeJSON call.

Thanks

Brian

Adam Tuttle

unread,
Dec 20, 2014, 10:52:34 AM12/20/14
to taffy...@googlegroups.com

If the only problem is key name case, use array notation: struct['key']=1 will result in {"key":1}

Brian C

unread,
Dec 20, 2014, 11:01:11 AM12/20/14
to taffy...@googlegroups.com
I need to make it exactly as described below.

Has to be an array named "widgets" (versus objects) and the numbering is also a no-no.

Brian

Brian C

unread,
Dec 20, 2014, 11:34:23 AM12/20/14
to taffy...@googlegroups.com
Ok so this is a terrible hack but getting the custom serializer going was not working out too well for me.

So I tried simply using: 

representationOf(deserializeJSON(theResult))

Worked great.

Yes I am probably a terrible person but for now I can move on and spend some time on the pesky IIS7 rewrite rule.

Depending on how that goes I may be posting again later today.

Brian 

Gerry Gurevich

unread,
Dec 20, 2014, 1:17:33 PM12/20/14
to taffy...@googlegroups.com
Might be too late to help now, but Ben Nadel has a great serializer.  Easy to use.  Can't say for sure it will work in your situation, but it's pretty good.

Brian C

unread,
Dec 20, 2014, 1:36:55 PM12/20/14
to taffy...@googlegroups.com
I think I have a reasonable workaround for today.

Next week I will take a look at the structures created by the deserializeJSON and see if that is something I can construct more elegantly than stringing a bunch of strings together into valid JSON.

Thanks anyway.

And in good news I got my wretched URL rewrite working.  That was quite painful.  But it is working....

Here it is if anyone is interested.  I did not find any examples online that were even close to what I needed so had to cobble this together using trial and error:

        <rewrite>
            <rules>
                <rule name="TaffyAPIRewriteRule" stopProcessing="false">
                    <match url="^api/v1/([^*]+)$" ignoreCase="false" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/api/v1/index.cfm?endpoint=/{R:1}" logRewrittenUrl="true" />
                </rule>
            </rules>
        </rewrite>

Brian

Adam Tuttle

unread,
Dec 20, 2014, 2:15:35 PM12/20/14
to taffy...@googlegroups.com

Seems to me your serialization issues can be entirely mitigated with proper coding. Creating JSON by hand is definitely not recommended, for a variety of reasons. I'm home now so in a few minutes I'll go grab my laptop and send you an example.

Adam Tuttle

unread,
Dec 20, 2014, 4:44:50 PM12/20/14
to taffy...@googlegroups.com
Sorry for the delay, got distracted dealing with family stuff.

<cfscript>
data = { "widgets" = [
    {
        "id" = 40252,
        "name" = "Some name",
        "dueDate" = "December, 31 2014 00:00:00"
    },
    {
        "id" = 43212,
        "name" = "Other name",
        "dueDate" = "December, 22 2014 00:00:00"
    }
]};

writeOutput(serializeJson(data));
</cfscript>

You didn't say what version of CF you're on so I assumed CF9, I think. With CF8 you can't do nested implicit object/array notation like this, you would have to compose each piece.

I tested on Railo 4 and CF10+, and this gives exactly the output that you need. In this case you would just return rep(data); in your taffy resource and let it do serializeJson.

Like I said, it seems like your only problem is the unintentional UCASE-ing of the object key names. When using literal notation like this, you can just quote the key names; if you're on ~CF8 you would do data = {}; data["widgets"] = []; ... -- just note the use of array notation instead of dots as in data.widgets. This makes sure that CF will represent the key in the case you provided in your declaration, rather than UCASE-ing it.

HTH,

Adam
Reply all
Reply to author
Forward
0 new messages