Grails render as JSON catch

Wednesday, November 21, 2012

One of a reasons your controller doesn't render a proper response in JSON format might be wrong package name that you use. It is easy to overlook. Import are on top of a file, you look at your code and everything seems to be fine. Except response is still not in JSON format.

Consider this simple controller:

class RestJsonCatchController {
    def grailsJson() {
        render([first: 'foo', second: 5] as grails.converters.JSON)
    }

    def netSfJson() {
        render([first: 'foo', second: 5] as net.sf.json.JSON)
    }
}

And now, with finger crossed... We have a winner!

$ curl localhost:8080/example/restJsonCatch/grailsJson
{"first":"foo","second":5}
$ curl localhost:8080/example/restJsonCatch/netSfJson
{first=foo, second=5}

As you can see only grails.converters.JSON converts your response to JSON format. There is no such converter for net.sf.json.JSON, so Grails has no converter to apply and it renders Map normally.

Conclusion: always carefully look at your imports if you're working with JSON in Grails!

Edit: Burt suggested that this is a bug. I've submitted JIRA issue here: GRAILS-9622 render as class that is not a codec should throw exception

7 comments:

  1. Seems like a bug - if net.sf.json.JSON isn't a codec it should throw an exception or log a warning, but certainly not render the argument's toString()

    ReplyDelete
    Replies
    1. Burt, I've submitted JIRA issue as you suggested: http://jira.grails.org/browse/GRAILS-9622 .

      Delete
    2. So, if I want my custom codec ( rende ['key':'value'] as OTHERTHING) it's just a matter of extend AbstractConverter?

      Or do I need to register it somewhere

      Delete
    3. @Eduardo - for a custom codec you have to write a class with a static encode closure. Take a look at documentation here: http://grails.org/doc/latest/guide/single.html#codecs . There is more info here: http://grails.org/Converters+Reference and example here: http://www.intelligrape.com/blog/2010/11/13/creating-custom-codec-in-grails/.

      Delete
  2. @Tomasz
    Thank you.
    I've already created a encode like the ones you have pointed.
    But that doesn't allow me to use the class just like a JSON or XML using the 'as' operator
    What I want is to be able to use it like

    render myObject as MYCUSTOMCODEC

    I've looked at the grails.converters.JSON class and it doesn't have the static encode closure


    thanks again

    ReplyDelete
  3. hell, i am tired to search to solve my problem but when i am reached your blog i solved my Grails Technology problem .so i want to say thanks to you to help me.

    ReplyDelete