GSON Serialiser Example [Java class의 JSON 변환]

GSON Serialiser Example

 

 

Java objects can be converted into JSON strings using the Gson API (Homepage). In this article we will see how we can convert Java objects into JSON strings using both the default Gson implementation and custom implementation.

The readers of this article are encouraged to read the articles: Simple Gson Example and Gson Deserialiser Example, if they are not familiar with Gson. Furthermore, this article is structured in the same way as the article Gson Deserialiser Example and the same examples are used here.

Observation

Please note the we will use the terms format or serialise interchangeably in this article.

All code listed below is available at: http://java-creed-examples.googlecode.com/svn/gson/Gson Serialiser Example/. Most of the examples will not contain the whole code and may omit fragments which are not relevant to the example being discussed. The readers can download or view all code from the above link.

Simple Example

Consider the following Java object.

package com.javacreed.examples.gson.part1;

public class Book {

  private String[] authors;
  private String isbn10;
  private String isbn13;
  private String title;

  // Methods removed for brevity

}

This is a simple Java class representing a book. Say that we need to serialise this class into the following JSON object.

{
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "isbn-10": "032133678X",
  "isbn-13": "978-0321336781",
  "authors": [
    "Joshua Bloch",
    "Neal Gafter"
  ]
}

Gson can seriliase the Book class without any special configuration, just using the default configuration. Gson uses the Java field names as the JSON names and will serialise their values accordingly. If we take a closer look to the JSON sample shown above, we will see that the ISBN fields contain a minus sign: isbn-10 and isbn-13. Unfortunately, we cannot obtain these field names using teh default Gson configuration. One way to address this problem is to use annotations as described in the article: Gson Annotations Example. Using annotations we can define the JSON field names and Gson will take case of the rest. Another approach is to use a JsonSerialiser (Java Doc) as shown in the following example.

package com.javacreed.examples.gson.part1;

import java.lang.reflect.Type;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class BookSerialiser implements JsonSerializer {

    @Override
    public JsonElement serialize(final Book book, final Type typeOfSrc, final JsonSerializationContext context) {
        final JsonObject jsonObject = new JsonObject();
        //The serialisation code is missing

        return jsonObject;
    }
}

The above example is not complete and we still need to add the most important thing, which is the serialisation. Let’s understand this class before we make it more complex by adding more code to it.

The interface JsonSerializer requires a type, which is the type of object that we will be serialised. In this case, we are serialising the Java object of type Book into JSON object. The return type of the serialize() method must be an instance of type JsonElement (Java Doc). As described in more detail in the article: Gson Deserialiser Example, the JsonElement has four concrete types listed below:

  • JsonPrimitive (Java Doc) – such as a string or integer
  • JsonObject (Java Doc) – a collection of JsonElements indexed by thier name (of type String). This is similar to a Map<String, JsonElement> (Java Doc)
  • JsonArray (Java Doc) – a collection of JsonElements. Note that the array elements can be any of the four types and mixed types are supported.
  • JsonNull (Java Doc) – a null value

a01.Types-of-JsonElement.png

 

Types of JsonElement

The above image shows all types of JsonElement. The JsonObject can be thought of a collection of name/value pairs where the values are of type JsonElement. Therefore, the values can yet be other objects.

Following is a complete example of our serialiser.

package com.javacreed.examples.gson.part1;

import java.lang.reflect.Type;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class BookSerialiser implements JsonSerializer {

    @Override
    public JsonElement serialize(final Book book, final Type typeOfSrc, final JsonSerializationContext context) {
        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("title", book.getTitle());
        jsonObject.addProperty("isbn-10", book.getIsbn10());
        jsonObject.addProperty("isbn-13", book.getIsbn13());

        final JsonArray jsonAuthorsArray = new JsonArray();
        for (final String author : book.getAuthors()) {
            final JsonPrimitive jsonAuthor = new JsonPrimitive(author);
            jsonAuthorsArray.add(jsonAuthor);
        }
        jsonObject.add("authors", jsonAuthorsArray);

        return jsonObject;
    }
}

We added some code here. Let us break this into smaller parts and understand each individual part before understanding the whole picture.

If we are to serialise this Java object, we first need to create the correct instance of the JsonElement. In our example we are returning an instance of JsonObject as our Book is an object as shown next.

    final JsonObject jsonObject = new JsonObject();

This object will be populated with our fields using the names we like as shown next

    // The variable 'book' is passed as a parameter to the serialize() method
    final JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("title", book.getTitle());
    jsonObject.addProperty("isbn-10", book.getIsbn10());
    jsonObject.addProperty("isbn-13", book.getIsbn13());

Using the addProperty() (Java Doc) method we can add any Java primitive together with Strings and Numbers. Note that the property name must be unique, otherwise it will replace the previous value. This can be thought of a Map (Java Doc) holding all values index by their name.

More complex objects such as Java objects and arrays cannot be added using the method shown above. The JsonObject has another method called add() (Java Doc), which can be used instead as shown below.

    // The variable 'book' is passed as a parameter to the serialize() method
    jsonObject.addProperty("title", book.getTitle());
    jsonObject.addProperty("isbn-10", book.getIsbn10());
    jsonObject.addProperty("isbn-13", book.getIsbn13());

    final JsonArray jsonAuthorsArray = new JsonArray();
    for (final String author : book.getAuthors()) {
      final JsonPrimitive jsonAuthor = new JsonPrimitive(author);
      jsonAuthorsArray.add(jsonAuthor);
    }
    jsonObject.add("authors", jsonAuthorsArray);

We first create the JsonArray and added all authors to it. Different from Java, we do not need to define the size of the array when initialising it. In fact, despite its name, we can think of the JsonArray class more as a list rather than array. Finally the variable jsonAuthorsArray is added to the json object. Note that we can add the jsonAuthorsArray to the jsonObject before adding its elements.

Before we can use our serialiser, we need to register it with Gson as shown below.

package com.javacreed.examples.gson.part1;

import java.io.IOException;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {

  public static void main(final String[] args) throws IOException {
    // Configure GSON
    final GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Book.class, new BookSerialiser());
    gsonBuilder.setPrettyPrinting();
    final Gson gson = gsonBuilder.create();

    final Book javaPuzzlers = new Book();
    javaPuzzlers.setTitle("Java Puzzlers: Traps, Pitfalls, and Corner Cases");
    javaPuzzlers.setIsbn10("032133678X");
    javaPuzzlers.setIsbn13("978-0321336781");
    javaPuzzlers.setAuthors(new String[] { "Joshua Bloch", "Neal Gafter" });

    // Format to JSON
    final String json = gson.toJson(javaPuzzlers);
    System.out.println(json);
  }
}

By registering our serialiser, we are instructing Gson to using this serialiser whenever an object of type Book is serialised.

In the example shown above, we also instructed Gson to format the JSON object, by invoking the set pretty printing shown next.

    gsonBuilder.setPrettyPrinting();

While this is useful for tutorials and debugging, please avoid this in production environment as this may produce larger JSON objects (in terms of text size) due to the formatting. Furthermore, pretty printing has a slight performance cost as Gson has to format the JSON objects and indent these accordingly.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

Running the above code will produce the desired JSON object. This concludes our first example of how to use a custom Gson serialiser to serialise Java objects into JSON objects. In the following section we will se how to serialise nested objects using Gson.

Nested Objects

In this example we will describe how to serialise nested objects, that is, objects within other objects. Here we will introduce a new entity, the author. A book, together with the title and ISBN can have a list of authors. The JSON object that will be produced in this example differs from the previous one to cater for the new entity as shown next:

{
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "isbn": "032133678X",
  "authors": [
    {
      "id": 1,
      "name": "Joshua Bloch"
    },
    {
      "id": 2,
      "name": "Neal Gafter"
    }
  ]
}

Note that in the previous example the authors were simply an array of strings as shown next:

  "authors": [
    "Joshua Bloch",
    "Neal Gafter"
  ]

In this example, the authors are JSON objects, not just primitives as shown next.

    {
      "id": 1,
      "name": "Joshua Bloch"
    }

The JSON author has an id and a name. Following is an example of the Author class.

package com.javacreed.examples.gson.part2;

public class Author {

  private int id;
  private String name;

  // Methods removed for brevity

}

This class is very straightforward. It comprise two fields, both JsonPrimitives. The Book class was modified to make use of the Author, as shown below.

package com.javacreed.examples.gson.part2;

public class Book {

  private Author[] authors;
  private String isbn;
  private String title;

  // Methods removed for brevity

}

The authors field was changed from an array of integers to an array of Authors. The BookSerialiser class has to be modified too in order to accommodate this change, as shown below.

package com.javacreed.examples.gson.part2;

import java.lang.reflect.Type;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class BookSerialiser implements JsonSerializer<Book> {

  @Override
  public JsonElement serialize(final Book book, final Type typeOfSrc, final JsonSerializationContext context) {
    final JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("title", book.getTitle());
    jsonObject.addProperty("isbn", book.getIsbn());

    final JsonElement jsonAuthros = context.serialize(book.getAuthors());
    jsonObject.add("authors", jsonAuthros);

    return jsonObject;
  }
}

The serialisation of the authors is delegated to the context (an instance of JsonSerializationContext (Java Doc) passed as a parameter to the serialize() method). The context will serialise the given objects and return a JsonElement. In turn the context will try to locate a serialiser that can serialise the given object and if none are found, it uses the default mechanism. For the time being we will not write a serialiser for the Author class, but instead we will use the default one.

package com.javacreed.examples.gson.part2;

import java.io.IOException;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {

  public static void main(final String[] args) throws IOException {
    // Configure GSON
    final GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Book.class, new BookSerialiser());
    gsonBuilder.setPrettyPrinting();
    final Gson gson = gsonBuilder.create();

    final Author joshuaBloch = new Author();
    joshuaBloch.setId(1);
    joshuaBloch.setName("Joshua Bloch");

    final Author nealGafter = new Author();
    nealGafter.setId(2);
    nealGafter.setName("Neal Gafter");

    final Book javaPuzzlers = new Book();
    javaPuzzlers.setTitle("Java Puzzlers: Traps, Pitfalls, and Corner Cases");
    javaPuzzlers.setIsbn("032133678X");
    javaPuzzlers.setAuthors(new Author[] { joshuaBloch, nealGafter });

    final String json = gson.toJson(javaPuzzlers);
    System.out.println(json);
  }
}

The above example, creates and configures Gson to use our BookSerialiser. We created two authors and a book and serialised the book. This will produce the JSON object shown at the beginning of this section.

For completeness we will also include a serialiser for the Author class as shown below.

package com.javacreed.examples.gson.part2;

import java.lang.reflect.Type;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class AuthorSerialiser implements JsonSerializer<Author> {

  @Override
  public JsonElement serialize(final Author author, final Type typeOfSrc, final JsonSerializationContext context) {
    final JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("id", author.getId());
    jsonObject.addProperty("name", author.getName());

    return jsonObject;
  }
}

The above serialiser introduces no new features and thus requires no explanation. In order to use this new serialiser we need to register it with the GsonBuilder (Java Doc).

This concludes the section about nested objects. Using the context, we can delegate the serialisation of nested objects to the context which will in turn locate the proper serialiser and produce the respective JsonElement. In the next and final section we will see how to deal with object references.

Object References

Objects refer to other objects and the books and authors classes are no exception. The same author can have many books. For example author Joshua Bloch (Author at Amazon), has several books. Using the serialiser described before, we will end up in duplicate authors.

Consider the following example:

package com.javacreed.examples.gson.part3;

import java.io.IOException;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Example1 {

  public static void main(final String[] args) throws IOException {
    // Configure GSON
    final GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setPrettyPrinting();
    final Gson gson = gsonBuilder.create();

    final Author joshuaBloch = new Author();
    joshuaBloch.setId(1);
    joshuaBloch.setName("Joshua Bloch");

    final Author nealGafter = new Author();
    nealGafter.setId(2);
    nealGafter.setName("Neal Gafter");

    final Book javaPuzzlers = new Book();
    javaPuzzlers.setTitle("Java Puzzlers: Traps, Pitfalls, and Corner Cases");
    javaPuzzlers.setIsbn("032133678X");
    javaPuzzlers.setAuthors(new Author[] { joshuaBloch, nealGafter });

    final Book effectiveJava = new Book();
    effectiveJava.setTitle("Effective Java (2nd Edition)");
    effectiveJava.setIsbn("0321356683");
    effectiveJava.setAuthors(new Author[] { joshuaBloch });

    final Book[] books = new Book[] { javaPuzzlers, effectiveJava };

    final String json = gson.toJson(books);
    System.out.println(json);
  }
}

Here we have two authors and two books. One of the author is shared between two books. Note that we have two author objects not three, as the instance representing Joshua Bloch is shared between both books. Finally note that we are not using any custom serialisers on purpose. The following is produced when executing the above code.

[
  {
    "authors": [
      {
        "id": 1,
        "name": "Joshua Bloch"
      },
      {
        "id": 2,
        "name": "Neal Gafter"
      }
    ],
    "isbn": "032133678X",
    "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases"
  },
  {
    "authors": [
      {
        "id": 1,
        "name": "Joshua Bloch"
      }
    ],
    "isbn": "0321356683",
    "title": "Effective Java (2nd Edition)"
  }
]

We have two JSON books and three JSON authors. The author: Joshua Bloch, shown below, is duplicated.

      {
        "id": 1,
        "name": "Joshua Bloch"
      }

This increases the size of the JSON object considerable, especially with more complex objects. Ideally, the book JSON object only contains the authors’ ids rather than the whole object. This resembles relational databases (Wiki) where the book has a foreign key (Wiki) to the authors table.

The Book class is modified to include a method that return just the authors’ ids as shown below.

package com.javacreed.examples.gson.part3;

public class Book {

  private Author[] authors;
  private String isbn;
  private String title;

  public Author[] getAuthors() {
    return authors;
  }

  public int[] getAuthorsIds() {
    final int[] ids = new int[authors.length];
    for (int i = 0; i < ids.length; i++) {
      ids[i] = authors[i].getId();
    }
    return ids;
  }

  // Other methods removed for brevity

}

When serialising the books we will use the authors’ id instead of the authors as shown next.

package com.javacreed.examples.gson.part3;

import java.lang.reflect.Type;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class BookSerialiser implements JsonSerializer {

  @Override
  public JsonElement serialize(final Book book, final Type typeOfSrc, final JsonSerializationContext context) {
    final JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("title", book.getTitle());
    jsonObject.addProperty("isbn", book.getIsbn());

    final JsonElement jsonAuthros = context.serialize(book.getAuthorsIds());
    jsonObject.add("authors", jsonAuthros);

    return jsonObject;
  }
}

Using this serialiser we will obtain the following:

[
  {
    "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
    "isbn": "032133678X",
    "authors": [
      1,
      2
    ]
  },
  {
    "title": "Effective Java (2nd Edition)",
    "isbn": "0321356683",
    "authors": [
      1
    ]
  }
]

Now instead of the whole author object we have just the author’s ids. This approach requires less space than the previous one where the whole author is serialised. This will have a huge effect on larger object graphs.

This example concludes this article about serialisation. Here we saw how we can serialise Java objects into JSON strings using default and custom serialisation options.

 

[출처] http://www.javacreed.com/gson-serialiser-example/

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
164 Java 8 개선 사항 관련 글 모음 졸리운_곰 2016.05.23 271
163 Building a Search Engine With Nutch Solr And Hadoop file 졸리운_곰 2016.04.21 219
162 Nutch and Hadoop Tutorial file 졸리운_곰 2016.04.21 209
161 Latest step by Step Installation guide for dummies: Nutch 0. file 졸리운_곰 2016.04.21 131
160 Nutch 초간단 빌드와 실행 졸리운_곰 2016.04.21 454
159 Nutch로 알아보는 Crawling 구조 - Joinc 졸리운_곰 2016.04.21 352
158 A tiny bittorrent library Java: 자바로 만든 작은 bittorrent 라이브러리 file 졸리운_곰 2016.04.20 242
157 Updating UI in Eclipse RCP 졸리운_곰 2015.11.07 183
156 Eclipse RCP: Display.getDefault().asyncExec still blocking my GUI 졸리운_곰 2015.11.07 135
155 The Eclipse RCP multi-threaded Job and UIJob, use 졸리운_곰 2015.11.07 243
154 SWT: Respond to Long Running Tasks 졸리운_곰 2015.11.07 91
153 SWT and multithreading 졸리운_곰 2015.11.07 73
152 Eclipse RCP multithreading 졸리운_곰 2015.11.07 146
151 Eclipse RCP - Prevent UI freezing while running long operation 졸리운_곰 2015.11.07 114
150 Eclipse RCP Tutorial: How to Add a Progress Bar file 졸리운_곰 2015.11.07 119
149 Eclipse RCP 에서 configuration 설정 파일 사용하지 않기 secret 졸리운_곰 2015.11.07 0
148 Gson User Guide 졸리운_곰 2015.10.26 318
147 Java Google Json (Gson) Type Adapter 졸리운_곰 2015.10.26 145
146 TypeAdapter (Gson 2.3.1 API) - Google Gson 졸리운_곰 2015.10.26 132
145 Gson TypeAdapter Example file 졸리운_곰 2015.10.26 86
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED