Sunday, November 7, 2010

GSON: JSON in just two lines of code, second part

As I mentioned in my last post, in this post we'll make a little more complicated example than the previous one. For those who have not yet revised the previous post, you can do it now using this link:


Well, now that we have reviewed the above example, we will modify the classes. Find the changes in bold:

import java.util.*;
public class Book
{
/** Name of the book*/
private String name;

/** number of pages*/
private Integer numPages;

/** How much the book costs*/
private Double cost;

/**authors's names*/
private String[] authors;

/** Publication Date*/
private Date published;

/** Pages of the book*/
private List<page> pages;


//Constructor, Getters and Setters...
}

public class Page
{
/** Number of the page*/
private int numPage;

/** Text of the page*/
private String text;

//Constructor, Getters and Setters...
}



import com.google.gson.Gson;
import java.util.*;
public class Control
{
public static void main(String[] args)
{
//create a book
         Book myBook = new Book();
         myBook.setName("Java and JSON");
         myBook.setNumPages(2);
         myBook.setCost(1.5);
         myBook.setAuthors(new String[]{"Alexis López", "Duke"});
         myBook.setPublished(new Date());


         //Create the pages
         Vector<Page> pages = new Vector();
         Page pOne = new Page();
         pOne.setNumPage(1);
         pOne.setText("This text is from page one");


         Page pTwo = new Page();
         pTwo.setNumPage(2);
         pTwo.setText("This text is from page two");


         pages.add(pOne);
         pages.add(pTwo);


         //Add the pages to the book
         myBook.setPages(pages);


//Convert myBook to JSON using GSON
         Gson gson = new Gson();
         String json = gson.toJson(myBook);

//print the result
System.out.println("*** MyBook as JSON ***");
         System.out.println(json);

         //Map JSON text to a new book
         Book newBook = gson.fromJson(json, Book.class);

         //print some attributes of the new book
System.out.println("*** NewBook from JSON ***");
         System.out.println("Name = " + newBook.getName());
         System.out.println("Authors = " + Arrays.toString(newBook.getAuthors()));
         System.out.println("Number of pages = " + newBook.getNumPages());
         System.out.println("Publication date = " + newBook.getPublished());
         System.out.println("Page One = " + 
                                         ((Page)(newBook.getPages().get(0))).getText());
         System.out.println("Page two = " + 
                                         ((Page)(newBook.getPages().get(1))).getText());
        //...
}
}


Note that we used java.util.List and not a java.util.Vector for the book's pages Collection. This is because GSON, when we are mapping the new Object, gson will try to use a java.util.LinkedList, and therefore it will not be compatible with java.util.Vector nor with java.util.ArrayList, producing the following exception:



Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.util.Vector field Book.pages to java.util.LinkedList
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
        at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
        at java.lang.reflect.Field.set(Field.java:657)
        at com.google.gson.FieldAttributes.set(FieldAttributes.java:182)
        at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler
(JsonObjectDeserializationVisitor.java:118)
        at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:158)

//...

For this reason we use java.util.List. The following console output is shown when you run the Control class:


*** MyBook as JSON *** 
{"name":"Java and JSON","numPages":2,"cost":1.5,"authors":["Alexis López","Duke"],"published":"7/11/2010 10:10:19 AM","pages":[{"numPage":1,"text":"This text is from page one"},{"numPage":2,"text":"This text is from page two"}]}

*** NewBook from JSON ***
Name = Java and JSON
Authors = [Alexis López, Duke]
Number of pages = 2
Publication date = Sun Nov 07 10:10:19 COT 2010
Page One = This text is from page one
Page two = This text is from page two


Thus, we can have Objects with relationships to another Objects and convert them to and from JSON.

In a future post, we will review examples with Java ME/JSON ME.

See you soon!


References:

google-gson. August 19 de 2010. Google Code [online]. Available from Internet:http://code.google.com/p/google-gson/ [accessed on October the 26th 2010].