01, past life
My name is Gson and I am an open source Java library for serializing Java objects into JSON strings and deserializing JSON strings into Java objects. From my name, you can see some clues, I am not unknown, I was born aristocrat, my father is Google, the market value of the richest country.
Of course, as a smart person, I am self-aware, in my father’s eyes, I am not the brightest star.
I came into the world by accident, or so my dad told me. He always said I’d picked it up by the river, though I never quite believed it. I confirmed this with my mother, who laughed from ear to ear and told me I was naive.
As I grew up, I liked to move around, so I got to know people like Jackson and Fastjson.
When I talk about Jackson, I always think of MJ, the king of pop who was taken away by God. Jackson has a 6.1K Star on GitHub, and although he doesn’t have as many fans as I do, I have a lot of respect for him as the default JSON parser for Spring Boot.
Fastjson comes from the mysterious East and has had some serious bugs, but that doesn’t stop it from becoming the most popular JSON parser out there, with more followers than ME, even though I already have over 18K stars.
People say we’re rivals, but I have to tell them that the three of us are as close as we can get to wearing the same underwear.
We all have our advantages. Jackson uses less memory at runtime, Fastjson is faster, and I can handle arbitrary Java objects, even without source code. Also, MY support for generics is much friendlier.
02. Add dependencies
Before you can use my API, you need to add me to your project. Maven and Gradle are recommended.
Maven:
< the dependency > < groupId > com. Google. Code. Gson < / groupId > < artifactId > gson < / artifactId > < version > 2.8.6 < / version > </dependency>Copy the code
Gradle:
Dependencies {implementation 'com. Google. Code. Gson: gson: 2.8.6'}Copy the code
Gradle is a project automation tool based on Apache Ant and Apache Maven concepts. Gradle build scripts are written using Groovy or Kotlin’s domain-specific language instead of traditional XML.
03. Performance
I don’t think so, it’s true. I’ve done a lot of testing, and I’m pretty good with JSON.
Test environment: Dual-core, 8GB ram, 64-bit Ubuntu operating system (desktop oriented Linux distribution)
Test results:
1) No problems with deserializing strings over 25M.
2) Can serialize collections of 1.4 million objects.
3) Can deserialize a collection of 87,000 objects.
4) Increase the deserialization limit for byte arrays and collections from 80K to more than 11M.
I’ve written the test cases for you and posted them on GitHub to verify them if you don’t believe me.
Github.com/google/gson…
04. Usage Guide
I don’t want to blow my own trumpet, but it’s true, I’m pretty easy to use, almost zero difficulty to get started. If you don’t believe me, you can try it.
I have a girlfriend with the same name as me, also named Gson, who provides my main functions. You can create it the rough and easy way of New Gson(), or you can call a guy called GsonBuilder and have him mail a copy over, really, I kid you not.
Let’s look at an example of serialization.
Gson gson = new Gson();
System.out.println(gson.toJson(18));
System.out.println(gson.toJson("Silence"));
System.out.println(gson.toJson(new Integer(18)));
int[] values = { 18.20 };
System.out.println(gson.toJson(values));
Copy the code
With the help of my girlfriend, you can pass basic data types int, String, wrapper type Integer, int array, and so on as arguments to the toJson() method, which will return a JSON String.
Take a look at the output:
18 "Silence" 18 [18,20]Copy the code
Let’s look at an example of deserialization.
Gson gson = new Gson();
int one = gson.fromJson("1".int.class);
Integer two = gson.fromJson("2", Integer.class);
Boolean false1 = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\" king 2 \ "", String.class);
String[] anotherStr = gson.fromJson("[\" silence \",\" King 2 \"]", String[].class);
System.out.println(one);
System.out.println(two);
System.out.println(false1);
System.out.println(str);
System.out.println(Arrays.toString(anotherStr));
Copy the code
The toJson() method is used for serialization, and the corresponding fromJson() method is used for deserialization. However, when deserializing, you need to specify the type of the argument, be it int or Integer, Boolean or String, or an array of Strings.
Take a look at the output:
1 2 false Wang Er [silence, Wang er]Copy the code
The above examples are relatively simple, and do not reflect my power.
Let’s customize a class:
public class Writer {
private int age = 18;
private String name = "Two";
private transient int sex = 1;
}
Copy the code
Then, we serialize it:
Writer writer = new Writer();
Gson gson = new Gson();
String json = gson.toJson(writer);
System.out.println(json);
Copy the code
The usage is as simple as before, so look at the output:
{" age ": 18," name ":" two "}Copy the code
Again, the result can be deserialized:
Writer writer1 = gson.fromJson(json, Writer.class);
Copy the code
There are some caveats that I need to remind you of.
1) The use of private fields is recommended.
2) There is no need to use any annotations to indicate which fields should be serialized and which fields should not be serialized. By default, this includes all fields, as well as fields inherited from the parent class.
3) If a field is decorated with transient keyword, it will not participate in serialization.
4) If the value of a field is null, it is not displayed in the serialized result.
5) Missing fields in JSON are set to default values after deserialization, with null for reference data types, 0 for numeric types, and false for Booleans.
Next, look at an example of a serialized collection.
List<String> list =new ArrayList<>();
list.add("Study hard.");
list.add("Up every day");
String json = gson.toJson(list);
Copy the code
The result is as follows:
[" Good good study "," Day day up "]Copy the code
When it comes to deserialization, it’s also very simple.
List<String> listResult = gson.fromJson(json,List.class);
Copy the code
The result is as follows:
Study hard and make progress every day.Copy the code
My girlfriend is a very careful and considerate person. When you call toJson() for serialization, she will first null to prevent throwing NPE, and then get the type of the parameter through getClass(), and then serialize it.
public String toJson(Object src) {
if (src == null) {
return toJson(JsonNull.INSTANCE);
}
return toJson(src, src.getClass());
}
Copy the code
But? For generics, getClass() drops the parameterized type. Consider the following example.
public class Foo<T> {
T value;
public void set(T value) {
this.value = value;
}
public T get(a) {
return value;
}
public static void main(String[] args) {
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
Bar bar = newBar(); foo.set(bar); String json = gson.toJson(foo); }}class Bar{
private int age = 10;
private String name = "Turing";
}
Copy the code
This can be observed if you go inside the toJson() method while debugging.
Foo’s actual type is foo
, but my girlfriend only gets foo when she calls foo.getClass(), which means she doesn’t know the actual type of foo.
Serialization is fine, deserialization is useless.
Foo<Bar> foo1 = gson.fromJson(json, foo.getClass());
Bar bar1 = foo1.get();
Copy the code
This code has an error at runtime.
Exception in thread "main" java.lang.ClassCastException: class com.google.gson.internal.LinkedTreeMap cannot be cast to class com.itwanger.gson.Bar (com.google.gson.internal.LinkedTreeMap and com.itwanger.gson.Bar are in unnamed module of loader 'app')
at com.itwanger.gson.Foo.main(Foo.java:36)
Copy the code
By default, the parameter type of the generic type is changed to LinkedTreeMap, which is obviously not the Bar we expected, and my girlfriend was upset about it.
As Google’s own son, I have “noble” in my blood, how can I bear the lonely girlfriend helpless.
So, I implanted two other methods in my girlfriend, one with Type parameters:
toJson(Object src, Type typeOfSrc);
<T> T fromJson(String json, Type typeOfT);
Copy the code
This way, when you serialize and deserialize generics, you can specify parameterized types for generics.
Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
String json = gson.toJson(foo,fooType);
Foo<Bar> foo1 = gson.fromJson(json, fooType);
Bar bar1 = foo1.get();
Copy the code
Debug looks inside the toJson() method to see the true type of foo.
FromJson () is similar in deserialization.
In this case, bar1 can be reached by calling foo1.get().
Look, HOW thoughtful I am, my girlfriend can not help but praise me!
05. Handle mixed types
As you know, Java does not recommend using mixed types, as in the following case.
List list = new ArrayList();
list.add("Silent King II.");
list.add(18);
list.add(new Event("gson"."google"));
Copy the code
The Event definition is as follows:
class Event {
private String name;
private String source;
Event(String name, String source) {
this.name = name;
this.source = source; }}Copy the code
Since a list does not specify a specific type, it can hold various types of data. It was easy, and my girlfriend had no problem serializing, but it was a lot harder to deserialize.
Gson gson = new Gson();
String json = gson.toJson(list);
System.out.println(json);
Copy the code
The following output is displayed:
[" gson", 18,{"name":"gson","source":" Google "}]Copy the code
When deserializing, it takes a little effort to get to the Event object.
JsonParser parser = new JsonParser();
JsonArray array = parser.parse(json).getAsJsonArray();
String message = gson.fromJson(array.get(0), String.class);
int number = gson.fromJson(array.get(1), int.class);
Event event = gson.fromJson(array.get(2), Event.class);
Copy the code
Yes, JsonParser was my predecessor. I hope you will not accuse me of cheating and playing with women’s feelings of men, really not my flower heart, because we are not suitable for some personality. But we’re still friends because there’s nothing wrong with either of us, it’s just that the code is more formal and there are fewer developers using hybrid types.
06, personalized customization
Considering that you are a person who pursues fashion, I have always set high standards for myself and strive to meet all your needs. This high standard makes my girlfriend both love and hate me.
I love my perfectionist attitude; Unfortunately, sometimes she’s out of her depth and can’t help.
When using toJson() to serialize Java objects, the return JSON string has no Spaces and is compact. If you want to print a prettier JSON format, you’ll need to call up an owner called GsonBuilder, ask him to do some customization, and then mail a copy to you, as I mentioned in the instructions.
public class Writer {
private int age = 18;
private String name = "Silent King II.";
public static void main(String[] args) {
Writer writer = new Writer();
Gson gson = new Gson();
String json = gson.toJson(writer);
System.out.println(json);
Gson gson1 = newGsonBuilder().setPrettyPrinting().create(); String jsonOutput = gson1.toJson(writer); System.out.println(jsonOutput); }}Copy the code
Compare the output:
{18, "age" : "name" : "silence reigned two"} {18, "age" : "name" : "silence reigned two"}Copy the code
With setPrettyPrinting(), the output format is more hierarchical and three-dimensional, with Spaces between fields and values, and newlines between different fields.
As mentioned earlier, my girlfriend ignores null fields when serializing by default, but she can also call GsonBuilder if she doesn’t want to.
public class Writer {
private int age = 18;
private String name = null;
public static void main(String[] args) {
Writer writer = new Writer();
Gson gson = new Gson();
String json = gson.toJson(writer);
System.out.println(json);
Gson gson2 = newGsonBuilder().serializeNulls().create(); String jsonOutput2 = gson2.toJson(writer); System.out.println(jsonOutput2); }}Copy the code
Compare the output:
{"age":18}
{"age":18,"name":null}
Copy the code
With serializeNulls(), null-valued fields are no longer ignored during serialization.
You may want to filter some fields during serialization and deserialization, and I have prepared several options for you. You can choose the one that suits you according to your taste.
First, through Java modifiers.
As you saw earlier, fields decorated with the TRANSIENT keyword will not participate in serialization and deserialization. Likewise, fields decorated with the static keyword do not. If you want to keep fields decorated with these keywords, you can do so.
Keep single species.
Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create();
Copy the code
Keep a variety.
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
.create();
Copy the code
Second, with @expose.
To use the @expose annotation, you need to do this first:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Copy the code
Add the @expose annotation to the fields that need to be serialized and deserialized; if not, the fields will be ignored.
@Expose
private int age = 18;
Copy the code
07, voice
If you want to learn more, please visit my GitHub page:
github.com/google/gson
I will tell you everything ABOUT me, everything except some secrets between me and my girlfriend, just to help you.
If you think I’m useful, please like me and leave a message, see you.
Recommended reading:
A three wire programmer, in 2020, counted and | Denver annual essay
GitHub star 115K + Java tutorial is awesome!