Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Translating nested Java objects to/from json using gson

Tags:

java

json

gson

Let's assume we have the following two Java Classes (omitting the other class members):

class Book {
    private String name;
    private String[] tags;
    private int price;
    private Author author;
}

class Author {
    private String name;
}

Furthermore, assume we have the following json object:

{"Book": {
    "name": "Bible",
    "price": 20,
    "tags": ["God", "Religion"],
    "writer": {
        "name": "Jesus"
    }
}

I am trying to find the best way to convert a Java Book instance to json and back using gson. To make the example more interesting, note that in json, I want to use "writer" instead of "Author". Can you please help? Ideally, I would like to see a complete implementation.

like image 754
happyhuman Avatar asked May 28 '14 18:05

happyhuman


2 Answers

Try with GsonBuilder#setPrettyPrinting() that configures Gson to output Json that fits in a page for pretty printing. This option only affects Json serialization.

Read more about Gson that is typically used by first constructing a Gson instance and then invoking below method on it.

  • toJson(Object) that serializes the specified object into its equivalent Json representation.

  • fromJson(String, Class) that deserializes the specified Json into an object of the specified class.


BookDetails Object to JSON String

Sample code:

Book book = new Book();
book.setName("Bible");
book.setTags(new String[] { "God", "Religion" });
book.setPrice(20);
Author author = new Author();
author.setName("Jesus");
book.setWriter(author);

BookDetails bookDetails = new BookDetails();
bookDetails.setBook(book);

String jsonString = new Gson().toJson(bookDetails);
// JOSN with pretty printing
// String jsonString = new GsonBuilder().setPrettyPrinting().create().toJson(bookDetails);
System.out.println(jsonString);

output:

{"Book":{"name":"Bible","tags":["God","Religion"],"price":20,"writer":{"name":"Jesus"}}}

JSON String to BookDetails Object

BookDetails newBookDetails = new Gson().fromJson(jsonString, BookDetails.class);

Here is the classes

class BookDetails {
    private Book Book;
    // getter & setter
}

class Book {
    private String name;
    private String[] tags;
    private int price;
    // Variable name should be writer instead of author as mapped to JSON string
    private Author writer; 
    // getter & setter
}

class Author {
    private String name;
    // getter & setter
}
like image 70
Braj Avatar answered Oct 01 '22 04:10

Braj


Thanks for all the answers. I was able to figure it out and implement it using some custom serializer and deserializer. Here is my own solution:

public class JsonTranslator {
    private static Gson gson = null;

    public void test(Book book1) {
        JsonElement je = gson.toJson(book1);  // convert book1 to json
        Book book2 = gson.fromJson(je, Book.class); // convert json to book2
        // book1 and book2 should be equivalent
    }

    public JsonTranslator() {

        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Book.class, new BookTrnaslator());
        builder.registerTypeAdapter(Author.class, new AuthorTrnaslator());
        builder.setPrettyPrinting();
        gson = builder.create();
    }


    private class BookTrnaslator implements JsonDeserializer<Book>, JsonSerializer<Book> {
        public Card deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            JsonObject jobj = json.getAsJsonObject();
            Book book = new Book();
            book.setName(jobj.get("name").getAsString());
            book.setTags(jobj.get("tags").getAsJsonArray()); //Assuming setTags(JsonArray ja) exists
            book.setName(jobj.get("price").getAsInt());
            book.setAuthor(gson.fromJson(jobj.get("writer"), Author.class));
            return book;
        }

       public JsonElement serialize(Book src, Type typeOfSrc, JsonSerializationContext context) {
            JsonObject jobj = new JsonObject();
            jobj.addProperty("name", src.getName());
            jobj.add("tags", src.getTagsAsJsonArray());
            jobj.addProperty("price", src.getPrice());
            jobj.add("writer", gson.toJson(src.getAuthor()));
            return jobj;
       }
    }

    private class AuthorTrnaslator implements JsonDeserializer<Author>, JsonSerializer<Author> {
        public Card deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            JsonObject jobj = json.getAsJsonObject();
            Author author = new Author();
            author.setName(jobj.get("name").getAsString());
            return author;
        }

       public JsonElement serialize(Author src, Type typeOfSrc, JsonSerializationContext context) {
            JsonObject jobj = new JsonObject();
            jobj.addProperty("name", src.getName());
            return jobj;
       }
    }
}
like image 26
happyhuman Avatar answered Oct 01 '22 05:10

happyhuman