Core and Advance features of Gson library
Welcome
back to last article on the Gson series. After reviewing the basics of Gson,
we'll discuss on some core and advance features of it.
All
the code is available on GitHub.
Before
moving further lets discuss what are the ways to create Gson object?
Gson object can
be created in two ways. First way gives you a quick Gson object provides
standard configuration and ready for faster coding, while second way uses GsonBuilder to build a more
sophisticated Gson object. By using GsonBuilder,
you can create a new Gson instance with your customized configuration.
Serialization/De-serialization
of Nested Objects
Gson
doesn't require any specific configuration to serialize/de-serialize nested
objects. It'll automatically infer the structure of the data based on the
passed classes. Like-
//Serialize (where bookObject is instance of Book.java)
String
serializedJson = gson.toJson(bookObject);
//
De-serialize
Book
book = gson.fromJson(INPUT_JSON, Book.class);
In
the GsonExample project refer NestedJsonTest.java
class for reference code.
Serialization/De-serialization
of Arrays/Lists
Arrays
If
you want to use Arrays in serialization/de-serialization, it's pretty simple.
You can directly use the fromJson() function as we've done before and pass the
model class as an array. Like
//Serialize
(where itemArray is array of Item.java)
String
serializedJson = gson.toJson(itemArray);
//
Deserialize
Item[]
items = gson.fromJson(INOUT_JSON, Item[].class);
List
Serialization
of List is also straight forward Like
//
Serialize
String
serializedJson = gson.toJson(myItemList);
In
order for Gson to understand the List
structure it provides a class TypeToken
to assist you in finding the correct Type. For our Item class in an ArrayList, it'd look like this:
Type
itemListType = new TypeToken<ArrayList<Item>>(){}.getType();
List<Item>
itemList = gson.fromJson(INOUT_JSON, itemListType);
In
the GsonExample project refer ArrayListJsonTest.java
class for reference code.
Important
point: Type and TypeToken are the very
important classes provided by GSON by which you can create expected data type.
For Map, Set or Generics you can also apply the same strategy to parse into appropriate
Type.
NULL values
During
serialization Gson ignores null values. If a value is not set, it'll not be part
of the resulting JSON. This behavior of ignoring null is a good idea to reduce
the size of resulting JSON.
If
you require that fields with null values in the JSON, Gson has an option for
it. We'll utilize the GsonBuilder to
adapt the serialization of null values.
Gson
gson = new GsonBuilder().serializeNulls().create();
String
serializedJson = gson.toJson(employeeDetails);
In
the GsonExample project refer NullValueJsonTest.java
class for reference code.
Ignore the
Fields
It
is useful in situations where you want to control if certain field should be
considered for Serialization/de-serialization. For that Gson offers a simpler
solution with the annotation @Expose.
This annotation is applied on field level and is effective only when Gson is
created with GsonBuilder and invoking
excludeFieldsWithoutExposeAnnotation().
In this
manner, only the field which is annotated with @Expose will be considered for
serializaion/deserialization.
@Expose offers two
configuration parameters: serialize and deserialize. By default both set to
true.
Like-
public class UserDetails { @Expose public String name; @Expose(deserialize = false) public String gender; @Expose(serialize = false, deserialize = false) public long phoneNumber; @Expose(serialize = false) public long cardNumber; public int pin; }
Gson
gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String
serializedJson = gson.toJson(userDetails);
In
the GsonExample project refer IgnoreFieldTest.java
class for reference code.
Change the
Name of Fields
So
far, we always assumed the JSON and model class have identical naming.
Unfortunately, this is not always the case. If are following Java or Android
naming convention, this can create a huge problem for you. In such situations
you can use @SerializedName annotation to make Gson's matching still work like
a charm.
public class UserData { public String name; public String gender; @SerializedName("phoneNumber") public long phoneNo; @SerializedName("cardNumber") public long cardNo; public int pin; }
In
the GsonExample project refer ChangeFieldNameTest.java class for reference code.
Naming Policy
We've
already learnt on how to use @SerializedName to change the single field inside
a model. However if you are in the initial face of development or Rest/Soap API and Java models are not
agreeing on specific naming it can be tedious to change hundreds of property
names with the @SerializedName annotation.
Thus,
Gson offers configured and custom FieldNamingPolicys.
This can be configured using GsonBuilder.
Once you set any of this policy, all conversions using the Gson instance will
now apply the field naming policy. In other words GSON conversion will follow
the name of fields according to the policy.
·
IDENTITY
·
LOWER_CASE_WITH_DASHES
·
LOWER_CASE_WITH_UNDERSCORES
·
UPPER_CAMEL_CASE
·
UPPER_CAMEL_CASE_WITH_SPACES
You
can find more details here.
Here
is example of LOWER_CASE_WITH_UNDERSCORES which split the property names based
on upper characters and replace those upper characters with a lower one leading
with underscore (_).
GsonBuilder
gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.
LOWER_CASE_WITH_UNDERSCORES);
Gson
gson = gsonBuilder.create();
{
"_name":
"UserName",
"gender":
"Male",
"phone_number":
1234567890,
"card_number": 283808120,
"pin": 4321
}
In
the GsonExample project refer FieldNamingPolicyTest.java
class for reference code.
Custom Type Adapters
Gson
does the serialization/deserialization using inbuilt adapters. In certain cases
you may want to write your own adapters because you want to change the default
behaviors or GSON does not provide adapter for your class.
To
achieve this you need to create a custom adapter by extending TypeAdapter class and passing it the
type of object targeted. Overrides read and write methods to do the custom de-serialization
and serialization respectively.
class
CustomAdapter extends TypeAdapter<Student> {
@Override
public UserDetails read(JsonReader
reader) throws IOException {
...
}
@Override
public void write(JsonWriter writer,
UserDetails userDetails) throws IOException {
…
}
}
And
then register the custom adapter using GsonBuilder as-
GsonBuilder
builder = new GsonBuilder();
builder.registerTypeAdapter(Student.class,
new StudentAdapter());
Gson
gson = builder.create();
In
the GsonExample project refer FieldNamingPolicyTest.java
class for reference code.
Hope
this article will help you to control over GSON.
To find more interesting topics on Software development follow me at https://medium.com/@ankit.sinhal
You can also find my Android Applications on play store
Comments
Post a Comment