Apr 21, 2017 Gson is used for serialization and de-serialization of Json. In this android app we download some data from the remote server in the form of json and perform json parsing using Gson.
- Create a new Android project in Eclipse. Target Android 1.6 or greater. Be sure to rename the startup activity Main.java. The next step is to download the Gson jar file.
- Oct 11, 2013 Download the latest version of GSON, and add it to your project by copying the jar file to the project's libs directory. If you do not see the jar file in your libs directory within Eclipse, right click and select Refresh Create two classes, Post and Tag. These will be our entity classes that model the data retrieved by the REST calls.
- Gson - Environment Setup - If you still want to set up a local environment for Java programming language, then this section will guide you on how to download and set up Java on your machi.
- Nov 10, 2016 Retrofit 2 — Adding & Customizing the Gson Converter by Norman Peitek on November 10 2016, tagged in Retrofit, Android, 5 min read.
Overview
Google's Gson library provides a powerful framework for converting between JSON strings and Java objects. This library helps to avoid needing to write boilerplate code to parse JSON responses yourself. It can be used with any networking library, including the Android Async HTTP Client and OkHttp.
Setup
Add the following line to your Gradle configuration:
Auto-generating Model Classes
You can auto-generate much of the model code as described in this guide. The generator will generated a large number of files that may be a bit overwhelming but the key is to parse the JSON to elements that you need. You can also see how a class is created for each nested layer in order to understand the manual process.
Generating Models Manually
First, we need to know what type of JSON response we will be receiving. The following example uses the Rotten Tomatoes API as an example and show how to create Java objects that will be able to parse the latest box office movies. Based on the JSON response returned for this API call, let's first define how a basic movie representation should look like:
By default, the Gson library will map the fields defined in the class to the JSON keys defined in the response. For instance, the fields
id
, title
, and year
will be mapped automatically. We do not need any special annotations unless the field names and JSON keys are different.In this specific case, the Movie class will correspond to each individual movie element and the Production class corresponds to the nested JSON object under movie's production element:
Initializing collections
![Download gson library for android download Download gson library for android download](/uploads/1/2/6/0/126004855/230676007.jpg)
Because the API returns a list of movies and not just an individual one, we also need to create a class that will map the
movies
key to a list of Movie objects.Note below that a public constructor may be needed to initialize the list. To avoid null pointer exceptions that may result from trying to get back the movie lists, it is highly recommended to initialize these objects in the empty constructor.
Parsing the response
Assuming we have the JSON response in string form, we simply need to use the Gson library and using the
fromJson
method. The first parameter for this method is the JSON response in text form, and the second parameter is the class that should be mapped. We can create a static method that returns back a BoxOfficeMovieResponse
class as shown below:Custom options
The Gson Builder class enables a variety of different options that help provide more flexibility for the JSON parsing. Before we instantiate a Gson parser, it's important to know what options are available using the Builder class.
Matching variable names to JSON keys
For instance, if our property name matches that of the JSON key, then we do not need to annotate the attributes. However, if we have a different name we wish touse, we can simply annotate the declaration with
@SerializedName
:Mapping Enums
Enums are not necessarily recommended by Google as described in this section. However, if you need to use them for decoding JSON responses, you can map them from string names. Suppose we had an enum of different colors:
We can annotate these attributes with
@SerializedName
too:Mapping camel case field names
There is also the option to specify how Java field names should map to JSON keys by default. For instance, the Rotten Tomatoes API response includes an
mpaa_rating
key in the JSON response. If we followed Java conventions and named this variable as mpaaRating
, then we would have to add a SerializedName
decorator to map them correctly:An alternate way, especially if we have many cases similar to this one, is to set the field naming policy in the Gson library. We can specify that all field names should be converted to lower cases and separated with underscores, which would caused camel case field names to be converted from
mpaaRating
to mpaa_rating
:Mapping Java Date objects
If we know what date format is used in the response by default, we also specify this date format. The Rotten Tomatoes API for instance returns a release date for theaters (i.e. '2015-08-14'). If we wanted to map the data directly from a String to a Date object, we could specify the date format:
Similarly, the date format could also be used for parsing standard ISO format time directly into a Date object:
In the event that Date fields need to mapped depending on the format, you are likely to need to need to use the custom deserializer approach described in the next section.
Mapping custom Java types
By default, the Gson library is not aware of many Java types such as Timestamps. If we wish to convert these types, we can also create a custom deserializer class that will handle this work for us.
Here is an example of a deserializer that will convert any JSON data that needs to be converted to a Java field declared as a Timestamp:
Then we simply need to register this new type adapter and enable the Gson library to map any JSON value that needs to be converted into a Java Timestamp.
Mapping multiple Date formats
If an API uses different Date formats, then a custom type adapter can be used to make parsing more robust. To use this approach, a default date policy should not be set by calling the method
setDateFormat()
as described in the earlier section. In addition, a custom deserializer should be registered and created:Leveraging the
DateUtils
class in the Apache Commons Language library, we can try multiple formats when attempting to parse a value to a Date field:Add this line to your Gradle file:
We can then use the parseDate() method to try multiple date formats:
Decoding collections of items
Sometimes our JSON response will be a list of items. We may also have declared a Java object and want to map the JSON response to a collection of these objects.
Since the Gson library needs to know what type should be used for decoding a string, we want to pass a type that defines a list of these objects. Because Java normally doesn't retain generic types because of type erasure, we need to implement a workaround. This workaround involves subclassing
TypeToken
with a parameterized type and creating an anonymous class:If are deserializing the string directly, we can use this custom type using the
fromJson()
method:This approach essentially creates a custom type for a list of objects for the Gson library. See this Stack Overflow discussion for more details.
HTTP Client Libraries
We can use any type of HTTP client library with Gson, such as Android Async HTTP Client or Square's OkHttp library.
Android Async HTTP Client
Gson Github
Be sure to use the
TextHttpResponseHandler
rather than JsonHttpResponseHandler
. Then you can access the response model to access the parsed data model. Retrofit 2
Retrofit uses OkHttp for the underlying networking library and can use the Gson library to decode API-based responses. To use it, we first need to define an interface file called
RottenTomatoesService.java
. To ensure that the API call will be made asynchronously, we also define a callback interface. Note that if this API call required other parameters, we should always make sure that the Callback
declaration is last.Then we can make sure to always inject the API key for each request by defining a
RequestInterceptor
. class. In this way, we can avoid needing to have it be defined for each API call.Next, we need to create a
Retrofit
instance with a Gson converter and make sure to associate the adapter to this RequestInterceptor
:We then simply need to create a service class that will enable us to make API calls: