JSON « Intelligrape Groovy & Grails Blogs

Posts Tagged ‘ JSON ’

Rendering JSON with formatting

Posted by on July 16th, 2012

In Grails, We often use

render list as JSON.

It renders json output without any formatting (spaces and new lines), often we need to provide users an option to receive formatted json (pretty printed) as response, so that it could easily be read and understood by users.

We can easily do that using

def json = doc as JSON
json.prettyPrint = true
json.render response

This renders json in pretty printed format, which is much easier for humans to read and understand.


Thanks

Sachin Anand
sachin[at]intelligrape[dot]com

@babasachinanand

Posted in Grails

Writing JSON APIs : Part II – Creating JSON Named Configs to Control What You Render

Posted by on December 29th, 2011

In the 1st part of the series, we looked at how to secure our application with Spring Security Basic Authentication and modifying the JSON Marshaller. However, it could often be the case that the same set of fields shouldn’t be returned on every JSON response.

For example, we could very well have a summary JSON for Book, which just returns the id and name of the Book, ignoring the other details like ISBN, genre etc. A real life example would be a Product’s complete details when returning JSON for its show view, while returning just the id, name and price for its view in a shopping cart.

In addition to that, we could choose, not to override the default JSON Marshallers provided by Grails so that the standard rendering method is not tampered.

Grails provides an excellent solution called “Named Configurations” which comes to our aid here. That, combined with some minor modifications on our CustomDomainClassJSONMarshaller can help us achieve this.

1. Add a static Map to the domain class, probably jsonProperties :

This property will hold the group name as key and the list of properties to be included as values.


//Book.groovy

static jsonProperties = [summary:['name']] //summary is the group name

2. Update the CustomDomainClassJSONMarshaller to have a property jsonPropertyGroup :

String jsonPropertyGroup
public CustomDomainClassJSONMarshaller(boolean includeVersion, GrailsApplication application, String jsonPropertyGroup = "") {
      this(includeVersion, new DefaultProxyHandler(), application, jsonPropertyGroup);
}
public CustomDomainClassJSONMarshaller(boolean includeVersion, ProxyHandler proxyHandler, GrailsApplication application, String jsonPropertyGroup) {
      this.includeVersion = includeVersion;
      this.proxyHandler = proxyHandler;
      this.application = application;
      this.jsonPropertyGroup = jsonPropertyGroup
}

3. Update the custom marshaller registrations to create Named Configs :

This method needs updation for two reasons

  • Calling the newly created constructors
  • API changes in grails 2.0

For creating a named config “summary”, we need to write something like


JSON.createNamedConfig(JSONConstants.SUMMARY_JSON_MARSHALLER_GROUP){
     it.registerObjectMarshaller(new CustomDomainClassJSONMarshaller(false, grailsApplication, "summary"), 2)
}

4. Using the newly registered named configs from within the controller:

This is the final step. We can use the named config with a static method JSON.use(), which takes in the configuration’s name and a closure inside which we will call the render <XYZ> as JSON method


JSON.use("summary"){
     render Book.list() as JSON
}

I have updated the example application to grails 2.0 and added an example to this approach.

Grails never ceases to amaze me. :)

Posted in Grails

Writing JSON APIs : Part I – Creating a secure JSON API with Grails and Spring Security in 3 easy steps

Posted by on November 16th, 2011

We had a requirement in a recent project to expose some of the functionality we had via a JSON API. The functionality needed to be secure, as was the initial web interface which exposed the functionality. We were using Spring Security for the security aspect of our application.

The spring security plugin, together with a secured controller and a custom JSON marshaller(which overrides the default functionality of render as JSON method) gave us a very simple, yet elegant and powerful JSON API which was secure. Here are the three steps that we followed

1. Setting up Spring Security Plugin:

The first step is to set up Spring Security Plugin to expose our JSON based controllers to use Basic Authentication, instead of the standard web based authentication. This is done by adding the lines given below in Config.groovy

//Enable Basic Auth Filter
grails.plugins.springsecurity.useBasicAuth = true
grails.plugins.springsecurity.basic.realmName = "JSON API Example"
//Exclude normal controllers from basic auth filter. Just the JSON API is included
grails.plugins.springsecurity.filterChain.chainMap = [
'/json/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
'/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
]

More details about the authentication mechanism can be found here.
2. Adding a Controller with required actions:

Naturally, this is the next step. We added a controller which would expose the functionalities required(another reason why most of our logic should be in our services instead of controllers). A sample controller would look like this.

package jsonapi
import grails.plugins.springsecurity.Secured
import grails.converters.JSON
import com.intelligrape.example.json.Book

@Secured(["ROLE_USER"])
class JsonController {
      def getBooks = {
          render Book.list() as JSON
      }
}

3. Customizing the Marshaller to change the way some properties like enums are rendered:

We had to change the way some of the properties like enums were going to be rendered. We just had to render the property name and the id of the enum. So instead of a json map like


"genre":{"enumType":"com.intelligrape.example.json.Book$Genre","name":"FICTION"}

we needed


"genre":"FICTION"

I sought help from David Bower’s post and created my own custom Domain Class Marshaller for JSON with a modification to just use the Enum value if the property happened to be an enum. This is a very powerful feature because it allows us to customize the way in which we want to render the values when creating a JSON or XML document from our classes. We can even customize it to have an excludes list in our domain class where we can specify the properties to be excluded while constructing our JSON or XML

With this, we had a JSON API ready in very little time. I have extracted the functionality into a small example application, which has been shared on Github.

Yet another example of how simple grails has made it easy for developers.

Posted in Grails

JQuery : create URL query string from JSON/Array

Posted by on May 4th, 2011

Hi Friends,
(more…)

JQuery: Send JSON Objects with an ajax request

Posted by on June 11th, 2010

Hi Friends,

Lets discuss today about sending JSON objects with ajax request using JQuery. We have number of functions in jQuery to kick-off an ajax request. But for sending JSON objects along with the request, I chose jQuer.ajax(). It takes various parameters url, type, data, dataType, beforeSend etc. Its API can be found here.

Lets look at example given below:

jQuery.ajax({
          url: <Url of the action>,
          type: "POST",
          data: {name: "amit", id:1 },
          dataType: "json",
          beforeSend: function(x) {
            if (x && x.overrideMimeType) {
              x.overrideMimeType("application/j-son;charset=UTF-8");
            }
          },
          success: function(result) {
 	     //Write your code here
          }
});

The above example works for simple JSON object. Now lets see how we can send JSON objects list as given below:

var jsonObjects = [{id:1, name:"amit"}, {id:2, name:"ankit"},{id:3, name:"atin"},{id:1, name:"puneet"}];
 
jQuery.ajax({
          url: <Url of the action>,
          type: "POST",
          data: {students: JSON.stringify(jsonObjects) },
          dataType: "json",
          beforeSend: function(x) {
            if (x && x.overrideMimeType) {
              x.overrideMimeType("application/j-son;charset=UTF-8");
            }
          },
          success: function(result) {
 	     //Write your code here
          }
});

If you notice, for sending my json objects it has not been written directly as data: jsonObjects. As it expects the JSON object passed to it written as key value pair. So we made students the key. And since we have json objects stored in a variable, we need to expand the json objects list using stringify(), otherwise it would be sent as a java script object.

Now on the server we can parse the JSON object, and use it as the list of objects of type map. For example

//this code is written in grails 
import grails.converters.JSON;
List<JSON> students = JSON.parse(params.students) //students in request params is parsed to json objects and stored in the List
println "Student id: " + students[0].studentId    //first element of the students list is accessed as a map holding a key studentId

Hope this helpled!

~~Amit Jain~~
amit@intelligrape.com

http://www.IntelliGrape.com

Tags: , ,

Create JSON object Using Grails converter (Only selective fields from lists of objects)

Posted by on May 13th, 2010

This post might help you if you want to get JSON (JavaScript Object Notation) Object on browser. Grails framework provides you very efficient way to achieve this.

For this you need to import grails JSON convertor in your code.

import grails.converters.JSON

Below is the code snapshot which converts java based lists of Objects to JSON object

HashMap jsonMap = new HashMap()
List<Company> companyList = Company.list()
List<Contact> employeeList = Employee.list()
 
jsonMap.companies = companyList.collect {comp ->
return [id: comp.id, name: comp.name, address: comp.address]
}
 
jsonMap.employees = employeeList.collect {emp ->
return [id: emp.id, name: emp.name, companyId: emp.companyId, role: emp.role]
}
 
render jsonMap as JSON

So you got it – MAGIC lies in “render jsonMap as JSON” statement.

Output sent to Browser:

{
  "companies": [
       {"id":281,"name":" Company Name Incorporated", "address": "street-address, zone-address, city, state, country, zip12"},
       {"id":282,"name":" Other company LLC", "address": "street-address1, zone-address2, city, state, country, zip34"},
  ],
  "employees": [
       {"id":123,"name":"Employee123 Name","companyId":281, "role":"Designer"},
       {"id":127,"name":"Employee127 Name","companyId":281, "role":"Supervisor"},
       {"id":129,"name":"Employee129 Name","companyId":282, "role":"Inspector"}
  ]
}

Isn’t it cool :-) . How to use JSON Objects on browser is out of scope of this post. I will try to write another post soon – how to query JSON based data to produce client-side results effectively (example – client side search).

Cheers!!
Salil Kalia

How to use $.getJSON() method of jQuery with grails?

Posted by on March 2nd, 2009

How to use $.getJSON() method of jQuery with grails?

Retriving a JSON string from Grails is very easy. You have to just write the following in your controller’s action

Let me explain you with an example of populating a HTML table using JSON response:
In this example, we have table with columns – name,address and gender. We want the table to be populated without doing a full page refresh, using an Ajax call.

Domain Class:

class MyDomain {
    String name
    String address
    String gender
}

Controller Class :

class MyController {
   def someaction = {
      List myDomains = MyDomain.findAllByGender(params.gender)
      <em>/*Let say 5 objects are retrieved*/</em>
      render myDomains as JSON
   }
}

The above code in action will render a JSON string in the following format:

[
{
"name" : "John",
"address" : "New York",
"gender" : "Male"
},
{
"name" : "Rob",
"address" : "Indonasia",
"gender" : "Male"
},
{
"name" : "Shayam",
"address" : "New Delhi",
"gender" : "Male"
},
{
"name" : "Chang",
"address" : "Thailand",
"gender" : "Male"
},
{
"name" : "Ali",
"address" : "London",
"gender" : "Male"
}
]

following script would be writtent on the client Side (in the GSP):

<script>
$.document.ready(function(){
$('#someid').click(function(){
<strong>$.getJSON</strong>("${createLink(controller:'my',action:'someaction')}",{gender:'Male', ajax: 'true'}, function(myDomains){
var myHTMLString = ''
for(var i = 0 ; i < myDomains.length ; i++)
{
myHTMLString = myHTMLString + '<tr><td>' + myDomains[i].name + '</td>'
myHTMLString = myHTMLString + '<tr><td>' + myDomains[i].address + '</td>'
myHTMLString = myHTMLString + '<tr><td>' + myDomains[i].gender + '</td></tr>'
}
$('table#mytable').html(myHTMLString)
})
})
})
</script>

The HTML code would be like this :

<div id=”someid”>
Click for JSON Response
</div>
<table id=”mytable”>
<!–empty table –>
</table>

When you click on the displayed text the html page would become like following:

<div id="someid">
Click for JSON Response
</div>
<table id="mytable">
<tr>
<td>John</td>
<td>New York</td>
<td>Male</td>
</tr>
<tr>
<td>Rob</td>
<td>Indonasia</td>
<td>Male</td>
</tr>
<tr>
<td>Shayam</td>
<td>New Delhi</td>
<td>Male</td>
</tr>
<tr>
<td>Chang</td>
<td>Thailand</td>
<td>Male</td>
</tr>
<tr>
<td>Ali</td>
<td>London</td>
<td>Male</td>
</tr>
</table>

any kind of suggestions and comments are welcome……

Regards,
Chandan Luthra

http://www.IntelliGrape.com