Friday, November 4, 2011

JSON versus JSONP with a GSON example

JSON is a data format used for passing data between webapps.
An example of JSON
{
"name" : "Freebase Reconciliation Service",
"identifierSpace" : "http://rdf.freebase.com/ns/type.object.mid",
"schemaSpace" : "http://rdf.freebase.com/ns/type.object.id",
"view" : {
"url" : "http://www.freebase.com/view{{id}}"
},
"preview" : {
"url" : "http://www.freebase.com/widget/topic{{id}}?mode=content",
"width" : 430,
"height" : 300
},
"suggest" : {
"property" : "http://standard-reconcile.freebaseapps.com/suggest_property"
},
"defaultTypes" : [
{
"id" : "/people/person",
"name" : "Person"
},
{
"id" : "/location/location",
"name" : "Location"
}
 ]
}

JSON is meant to be used only within the same domain, a domain of origin thing to prevent its from being vulnerable to cross site scripting, like what was exploited like crazy when I was a young one just learning Java. But that's not always a very convenient solution for everyone, sometimes you just need to get JSON-based data from a 3rd party site (after all JSON has advantages over other methods), so what to do?

JSONP was developed to solve this. JSONP looks almost entirely just like JSON, even in name. An example of JSONP where "foo" is added to the call in form of a callback value
(i.e. http://www.mydomain.com/mywebapp?callback=foo):
foo({
  "name" : "Freebase Reconciliation Service",
  "identifierSpace" : "http://rdf.freebase.com/ns/type.object.mid",
  "schemaSpace" : "http://rdf.freebase.com/ns/type.object.id",
  "view" : {
    "url" : "http://www.freebase.com/view{{id}}"
  },
  "preview" : {
    "url" : "http://www.freebase.com/widget/topic{{id}}?mode=content",
    "width" : 430,
    "height" : 300
  },
  "suggest" : {
    "property" : "http://standard-reconcile.freebaseapps.com/suggest_property"
  },
  "defaultTypes" : [
    {
      "id" : "/people/person",
      "name" : "Person"
    },
    {
      "id" : "/location/location",
      "name" : "Location"
    }
  ]
})

So if you're like me, and thinking GSON is neat and you want to use it, but need the data to be packaged in JSONP format, it's rather easy to fix this..

   // Okay, it doesn't have to have the setPrettyPrinting,
  // but it helps make it readable when troubleshooting!

   Gson gson = new GsonBuilder().setPrettyPrinting().create();;
    response.setCharacterEncoding("UTF-8");
                 response.setContentType("application/json");
           response.setStatus(200);

   PrintWriter out= response.getWriter();
   String JSONstr = gson.toJson(object2beJSONized);
   String callback = request.getParameter("callback");
   JSONstr = callback+"("+JSONstr+");";
   out.print(test);

Ta-da~!

I'm posting this because I really wish there had been this easy of an explanation for how to do this somewhere online.

2 comments:

  1. Hi!!

    I hope you can help me... I have a restful web service made with java/jersey deployed in openshift.

    The Android application I'm developing can access the API and exchange data (get, post...), but my web backend can't through Jquery and ajax...

    The call seems to be correctly made as firebug tells me 200 OK and as I can see the JSON text correctly.

    The thing is that as dataType: "jsonp" can't be deleted (otherwise it isn't working nor from browser at least), I think that my json is not in JSONP format (with call back and so on).

    Could you help me with that?

    my email is captain06@gmail.com

    Thanks in advance.

    ReplyDelete
  2. "JSON is meant to be used only within the same domain" - No, it is _Ajax_ (using JSON, XML or any other data format) that is only meant to be within the same domain. JSON as a data format can be used between any two systems that can handle strings.

    ReplyDelete