Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Introduction and usage of Gson

2025-04-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the relevant knowledge of "introduction and use of Gson". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Introduction to Gson

Before formally introducing Gson, we can take a look at the description of Gson from the official wiki to see what it is.

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object .

As you can see from the description, Gson is a Java library used to convert Java objects to and from JSON formatted string data. It was initially widely used within Google on the Android platform and on Java servers. After open source in 2008, it has become another widely used open source framework for Google. As of now * (2019.09.08) * there are 1W6 multiple stars on GitHub, and the same class libraries include Jackson integrated in Spring Framework and fastjson of Ali open source.

In terms of features, Gson provides a simple API fromJson/toJson to achieve the conversion between Java and JSON, and can generate compact, readable JSON string output, but also supports complex object conversion and rich custom representation, sufficient to meet most of our daily development needs of JSON data processing.

We usually refer to the conversion between objects and JSON strings as serialization and deserialization (Serialization/Deserialization). The process of converting an object into an JSON string is called serialization, and the process of converting an JSON string into an object is called deserialization.

Basic use of Gson

Serialization and deserialization operations using the Gson framework are inseparable from the com.google.gson.Gson object, which is also the key object of the Gson framework. The public API provided has a variety of serialization and deserialization methods.

There are two main ways to create Gson objects:

Create directly using the new keyword: Gson gson = new Gson ()

Built from GsonBuilder object: Gson gson = new GsonBuilder () .create ()

In general, the Gson objects created in the above two ways behave the same when serializing and deserializing, but the second way to build Gson objects allows for additional behavior customization, such as formatting the output of JSON strings, serializing null values, and so on.

Java serialization of simple objects

We can use the following example to see the different effects of serializing Java objects in the above two ways:

Public class ResultTest {@ Test void test_serialization () {Gson gson = new Gson (); Result result = new Result (200, "success", null); String json = gson.toJson (result); System.out.println ("json is" + json); Gson buildedGson = new GsonBuilder (). SetPrettyPrinting (). SerializeNulls (). Create (); String buildedJson = buildedGson.toJson (result) System.out.println ("buildedJson is" + buildedJson);} class Result {private int code; private String message; private Object data; public Result (int code, String message, Object data) {this.code = code; this.message = message; this.data = data;}

Run the test case, and you can see the following log output in the console:

As you can see from the results, the default Gson object behavior will ignore the null value field when serializing the object, while the com.google.gson.GsonBuilder#serializeNulls method will allow the Gson object to serialize the null field; and the normally serialized JSON string is a compact format, saving string memory, and the final output JSON string after using the com.google.gson.GsonBuilder#setPrettyPrinting method is a more readable format. Of course, in addition to these two methods, GsonBuilder also provides a lot of API for customizing serialization and deserialization behavior, which we will explain later.

JosnObject generates JSON

In addition to the above way of converting objects of a custom class to JSON, you can also use the JsonObject provided by the Gson framework to build a normal object, then use the toJson method to generate a JSON string, add the following test class to the original test class, and run to see the following results

@ Testvoid test_jsonObject_serialization () {Gson gson = new Gson (); JsonObject jsonObject = new JsonObject (); jsonObject.addProperty ("code", 400); jsonObject.addProperty ("message", "parameter error"); String toJson = gson.toJson (jsonObject); String exceptedJson = "{\" code\ ": 400,\" message\ ":\" Parameter error\ "; Assertions.assertEquals (exceptedJson, toJson); / / true}

JsonObject can only be used to add these four types of data by using the addProperty (property,value) method, because the internal is to call com.google.gson.JsonObject#add, encapsulating the value into a JsonPrimitive object, and then saving it to the internal custom LinkedTreeMap collection variable members; if you need to add other objects on the JsonObject object, you need to add a JsonElement object directly using the add (String property, JsonElement value) method. JsonElement here is an abstract class, and both JsonObject and JsonPrimitive inherit JsonElement, so we end up using another JsonObject object as the property object on the original JsonObject:

Gson gson = new Gson (); JsonObject jsonObject = new JsonObject (); / /... JsonObject nestJsonObject = new JsonObject (); nestJsonObject.addProperty ("username", "one"); nestJsonObject.addProperty ("score", 99); jsonObject.add ("data", nestJsonObject); String toJson2 = gson.toJson (jsonObject); System.out.println (toJson2) / / {"code": 400, "message": "Parameter error", "data": {"username": "one", "score": 99}} JSON deserializes the deserialization of simple objects

Now let's take a look at the use of JSON deserialization into Java objects. The main method here is com.google.gson.Gson#fromJson. Its most basic use is fromJson (String json, Class classOfT). You try to convert a JSON string into an object with a specified Class. If the conversion fails, a JsonSyntaxException exception will be thrown. We can add a test case to the original code and run it to see the effect:

@ Testvoid test_deserialization () {String json = "{\" code\ ": 400,\" message\ ":\" Parameter error\ "; Result result = new Gson () .fromJson (json, Result.class); Assertions.assertEquals (400, result.code); / / true Assertions.assertEquals (" Parameter error ", result.message); / / true} deserialize Map

In addition to serializing JSON strings into custom Java objects, we can also convert them to Map collections, where Gson provides conversion to Map collections and is easy to use:

@ Testvoid test_map () {String jsonString = "{'employee.name':'one','employee.salary':10}"; Gson gson = new Gson (); Map map = gson.fromJson (jsonString, Map.class); assertEquals (2, map.size ()); assertEquals ("one", map.get ("employee.name")); assertEquals (Double.class, map.get ("employee.name"). GetClass ();}

It should be noted that the real type of the converted Map object is not the HashMap that we often use, but the Gson custom collection LinkedTreeMap, which implements the Map interface to store key-value pairs, optimizes the implementation of adding and deleting them, and takes the order of storing key-value pairs as the traversal order, that is, the first stored is traversed first. In addition, the numerical data in the JSON string will be converted to the Double type, and the true/false data will be converted to the Boolean type, which can be judged according to the implementation of the com.google.gson.internal.bind.ObjectTypeAdapter#read method.

JSON to Array,List conversion JSON to Array

When we are doing array conversion on JSON data, it is similar to normal object conversion. The toJson method is directly converted to JSON data, and fromJson specifies that the array type is converted to an array of the corresponding type.

@ Testvoid test_array () {Gson gson = new Gson (); int [] ints = {1 abc, "def", "ghi"}; String [] strings = {"abc", "def", "ghi"}; String s = gson.toJson (ints); / / [1MIT 2PME 3PM5] assertEquals ("[1MIT 2MIT 3Jing 3Jing 4Jing 5], s); / / true String S1 = gson.toJson (strings) / ["abc", "def", "ghi"] assertEquals ("[\" abc\ ",\" def\ ",\" ghi\ "], S1); String [] strings1 = gson.fromJson (S1, String [] .class); assertEquals (strings.length, strings1.length); / / true assertEquals (strings [0], strings1 [0]); / / true int [] ints2 = gson.fromJson AssertEquals (1, ints2 [0]); / / true assertEquals (5, ints2 [4]); / / true} JSON conversion List

To convert List data into JSON data, use Gson in the same way as dealing with Array data. Here, the operation of converting JSON data into List objects is slightly different. To convert an JSON array data into a List of a custom class, we write it as follows:

@ Testpublic void givenJsonString_whenIncorrectDeserializing () {Gson gson = new Gson (); String inputString = "[{\" id\ ": 1,\" name\ ":\" one\ "}, {\" id\ ": 2,\" name\ ":\" two\ "}"; List outputList = gson.fromJson (inputString, List.class); outputList.get (0). GetId ();}

Unfortunately, a ClassCastException exception is thrown after running this code, which is described as follows:

Java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.one.learn.Person...

From the above description, we can see that after fromJson is executed, the deserialized List element is of type LinkedTreeMap, not Person, so a ClassCastException exception is thrown when accessing the id property as a Person object. What should we do with it? we need to call another fromJson method of Gson: fromJson (String json, Type typeOfT). Let's take a look at how to use it.

@ Testpublic void givenJsonString_whenCorrectDeserializing_ () {Gson gson = new Gson (); String inputString = "[{\" id\ ": 1,\" name\ ":\" one\ "}, {\" id\ ": 2,\" name\ ":\" two\ "}]"; Type type = new TypeToken () {} .getType (); List outputList = gson.fromJson (inputString, type); int id = outputList.get (0). GetId (); assertEquals (1, id) / / true assertEquals ("one", outputList.get (0) .getName ()); / / true}

The Type object in this method is obtained through the getType method of the TypeToken object, which is the generic type associated with the TypeToken object. Here TypeToken is a class introduced by Gson to support generics to solve the problem that Java cannot provide generic type representation. Because the construction method of TypeToken is modified by protected and cannot be constructed directly, it needs to be written in the form of new TypeToken () {} .getType ().

Advanced usage of Gson

After touching on the basic use of Gson, we went on to learn more about other uses of Gson.

Deserialization of generic objects

The previous section briefly touched on Gson's support for generics, and then use the code to show its power. First, we adjust the Result class above to accept generic parameters:

Class Result {private int code; private String message; private T data; public Result (int code, String message, T data) {this.code = code; this.message = message; this.data = data;}}

Then parse a JSON string with an embedded object into a Result object. The sample code is as follows:

@ Testvoid test_genric_object () {String json = "{\" code\ ": 200,\" message\ ":\" Operation succeeded\ ",\" data\ ": {\" username\ ":\" one\ ",\" avater\ ":\" image.jpg\ "" + "}}"; Type type = new TypeToken () {} .getType (); Result result = new Gson (). FromJson (json, type); Assertions.assertEquals (200, result.code) Assertions.assertEquals ("one", result.data.getUsername ()); Assertions.assertEquals ("image.jpg", result.data.getAvater ());} class User {private String username; private String avater; public String getUsername () {return username;} public String getAvater () {return avater;}}

Use the TypeToken object to get the specific generic type Result, and then pass it in the fromJson method to deserialize based on the corresponding type.

Custom serialization

If we want to perform special handling on some fields of the Java object, such as hiding the serialization of some fields, formatting the data of the fields, etc., we can customize the serialization logic by implementing the JsonSerializer interface. For example, we need to handle the Date type property in a specific format, and we can declare that the DateSerializer class implements as follows:

Class DateSerializer implements JsonSerializer {SimpleDateFormat dateTime = new SimpleDateFormat ("yyyy-MM-dd"); @ Override public JsonElement serialize (Date src, Type typeOfSrc, JsonSerializationContext context) {return new JsonPrimitive (dateTime.format (src));}}

Then, before building the Gson object, register the DateSerializer instance with GsonBuilder, as follows:

Gson gson = new GsonBuilder () .registerTypeAdapter (Date.class, new DateSerializer ()) .create ()

In this way, whenever you encounter a field of type Date to be serialized, the date is output in yyyy-MM-dd format through a custom serialize method, as shown in the sample code below:

@ Testvoid test_dateSerializer () {MyObject myObject = new MyObject (new Date (), "one"); Gson gson = new GsonBuilder (). RegisterTypeAdapter (Date.class, new DateSerializer ()). Create (); String json = gson.toJson (myObject); String exceptedJson = "{\" date\ ":\" 2019-09-08\ ",\" name\ ":\" one\ "}"; Assertions.assertEquals (exceptedJson, json); / / true} class MyObject {private Date date; private String name Public MyObject (Date date, String name) {this.date = date; this.name = name;} public MyObject () {}} Custom deserialization

Similar to the custom serialization implementation, if you want to customize the deserialization logic, you need to implement an interface called JsonDeserializer to implement the custom deserialization logic. For example, there is a JSON string whose content is {"CODE": 400, "MESSAGE": "parameter error"}, which needs to be deserialized into the Result object mentioned earlier. Because the field names are different, in order to implement the corresponding conversion, you need to customize the ResultDeserializer class, as shown below:

Class ResultDeserializer implements JsonDeserializer {@ Override public Result deserialize (JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {JsonObject object = json.getAsJsonObject (); Result result = new Result (object.getAsJsonPrimitive ("CODE"). GetAsInt (), object.getAsJsonPrimitive ("MESSAGE"). GetAsString (), null); return result;}}

The next step is to register the ResultDeserializer instance with GsonBuilder, generate the corresponding Gson object, and deserialize it:

@ Testvoid test_resultDeserializer () {/ / language=JSON String json = "{\" CODE\ ": 400,\" MESSAGE\ ":\" Parameter error\ "; Gson gson = new GsonBuilder () .registerTypeAdapter (Result.class, new ResultDeserializer ()) .create (); Result result = gson.fromJson (json, Result.class); Assertions.assertEquals (400, result.code) / / true Assertions.assertEquals ("parameter error", result.message); / / true} Gson common notes

In addition to providing some API for developers to use, Gson also has some feature annotations that can be used. Here are some of the most commonly used annotations in Gson.

@ Expose

This annotation can only be used on fields to indicate whether the corresponding field will be exposed during serialization or deserialization. There are two properties, serialize and deserialize, which are both true by default. When you annotate a field @ Expose (serialize = true, deserialize = false), it indicates that the field is visible during serialization and that assignment is ignored when deserialization occurs. It is important to note that the @ Expose annotation is limited only when building Gson with GsonBuilder, and the excludeFieldsWithoutExposeAnnotation method must be called before building. Here is a specific example:

@ Testvoid test_expose () {MySubClass subclass = new MySubClass (42L, "the answer", "Verbose field not to serialize"); MyClass source = new MyClass (1L, "foo", "bar", subclass); Gson gson = new GsonBuilder (). ExcludeFieldsWithoutExposeAnnotation (). Create (); String s = gson.toJson (source); System.out.println (s) / / {"id": 1, "name": "foo", "subclass": {"id": 42, "description": "the answer", "otherVerboseInfo": "Verbose field not to serialize"}} @ Data@AllArgsConstructorclass MyClass {private long id; @ Expose (serialize = false, deserialize = true) private String name; private transient String other; @ Expose private MySubClass subclass;} @ Data@AllArgsConstructorclass MySubClass {@ Expose private long id; @ Expose private String description @ Expose private String otherVerboseInfo;}

Fields modified by the transient keyword in Gson are not serialized and deserialized by default, which is consistent with Java native serialization and deserialization operations.

@ Since

This annotation is used to mark the version of the corresponding field or type so that Gson can specify the version number for serialization and deserialization. This annotation is useful when there are multiple versions of fields for the class corresponding to the JSON data on the Web service.

Similarly, this annotation is only for Gson objects built using GsonBuilder, and is valid when the version number is specified using the setVersion method, and only the fields of the corresponding version in the object are parsed. The following is a specific example:

Public class VersioningSupportTest {@ Test void test () {VersionedClass versionedObject = new VersionedClass (); Gson gson = new GsonBuilder (). SetVersion (1. 0). Create (); String jsonOutput = gson.toJson (versionedObject); System.out.println (jsonOutput); / / {"newField": "new", "field": "old"}} class VersionedClass {@ Since (1.1) private final String newerField @ Since (1.0) private final String newField; private final String field; public VersionedClass () {this.newerField = "newer"; this.newField = "new"; this.field = "old";}} @ SerializedName

This annotation is easy to use and useful. @ SerializedName specifies the name under which member fields are serialized and deserialized. Here is how to use them:

Public class JSONFieldNamingSupportTest {private class SomeObject {@ SerializedName ("custom_naming") private final String someField; private final String someOtherField; public SomeObject (String a, String b) {this.someField = a; this.someOtherField = b;} @ Test void test () {SomeObject someObject = new SomeObject ("first", "second") String jsonRepresentation = gson.toJson (someObject); System.out.println (jsonRepresentation); / / {"custom_naming": "first", "someOtherField": "second"} SomeObject someObject1 = gson.fromJson (jsonRepresentation, SomeObject.class); System.out.println (someObject1); / / SomeObject {someField='first', someOtherField='second'}} @ JsonAdapter

Different from the above note, @ JsonAdapter only acts on the class, and its main function is to replace the execution of the GsonBuilder.registerTypeAdapter method. Specifying the JsonDeserializer object or the JsonSerializer object directly through the @ JsonAdapter (aClass.class) method can have the same thought, and has a higher priority than GsonBuilder.registerTypeAdapter. Since the execution of the registerTypeAdapter method is simplified to an annotation method, it will not be demonstrated here. You can see the effect by using it directly on the Result class in the previous custom deserialization section.

Conclusion

This article mainly summarizes the use of serialization and deserialization of the Gson framework, as well as introduces the use of various features of Gson, hoping to be helpful to those who have a headache in dealing with JSON data.

This is the end of the introduction and usage of Gson. Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report