Java?JSON處理庫(kù)之Gson的用法詳解
引言
JSON(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式,易于閱讀和編寫(xiě),同時(shí)也易于機(jī)器解析和生成。在Java項(xiàng)目中,JSON被廣泛應(yīng)用于各種場(chǎng)景,例如Web應(yīng)用程序中的數(shù)據(jù)傳輸、配置文件、日志記錄等。隨著Java開(kāi)發(fā)人員對(duì)JSON處理需求的增長(zhǎng),諸多JSON處理庫(kù)應(yīng)運(yùn)而生,旨在簡(jiǎn)化和優(yōu)化JSON數(shù)據(jù)的操作。
在Java領(lǐng)域,處理JSON數(shù)據(jù)的常見(jiàn)庫(kù)有Jackson、Gson等。這些庫(kù)各有優(yōu)缺點(diǎn),具體的選擇取決于項(xiàng)目的需求和開(kāi)發(fā)者的喜好。本文將重點(diǎn)介紹Google開(kāi)發(fā)的Gson庫(kù),包括其基本功能、高級(jí)特性以及如何在實(shí)際項(xiàng)目中使用Gson來(lái)處理JSON數(shù)據(jù)。
Gson簡(jiǎn)介
Gson是Google開(kāi)發(fā)的一款Java JSON處理庫(kù),旨在簡(jiǎn)化Java開(kāi)發(fā)人員操作JSON數(shù)據(jù)的過(guò)程。Gson庫(kù)的核心功能是將Java對(duì)象轉(zhuǎn)換為JSON表示(序列化)以及將JSON字符串轉(zhuǎn)換為等效的Java對(duì)象(反序列化)。它的設(shè)計(jì)注重簡(jiǎn)潔易用,API直觀且易于學(xué)習(xí)。
Gson在性能方面表現(xiàn)優(yōu)秀,雖然可能不是最快的JSON庫(kù),但它的性能足夠滿足大多數(shù)應(yīng)用場(chǎng)景的需求。此外,Gson擁有豐富的特性和選項(xiàng),可以滿足不同項(xiàng)目的需求和定制化需求。
官方網(wǎng)站:github.com/google/gson
Gson的基本功能
Gson庫(kù)提供了一些簡(jiǎn)單易用的功能來(lái)處理JSON數(shù)據(jù)。以下是Gson的兩個(gè)核心功能:
1. 將Java對(duì)象轉(zhuǎn)換為JSON字符串(序列化)
Gson可以將Java對(duì)象轉(zhuǎn)換為JSON格式的字符串。這個(gè)過(guò)程通常被稱為序列化。Gson通過(guò)分析對(duì)象的屬性和值來(lái)生成相應(yīng)的JSON表示。例如:
Person person = new Person("John Doe", 30); Gson gson = new Gson(); String json = gson.toJson(person); System.out.println(json);
輸出結(jié)果:
{
"name": "John Doe",
"age": 30
}
2. 將JSON字符串轉(zhuǎn)換為Java對(duì)象(反序列化)
Gson還可以執(zhí)行反向操作,即將JSON字符串轉(zhuǎn)換為對(duì)應(yīng)的Java對(duì)象。這個(gè)過(guò)程通常被稱為反序列化。例如:
String json = "{\"name\":\"John Doe\",\"age\":30}"; Gson gson = new Gson(); Person person = gson.fromJson(json, Person.class); System.out.println(person);
輸出結(jié)果:
Person{name='John Doe', age=30}
使用Gson的基本步驟
要在項(xiàng)目中使用Gson庫(kù),可以遵循以下基本步驟:
1. 添加依賴
首先,需要將Gson庫(kù)添加到項(xiàng)目的依賴中。根據(jù)你的項(xiàng)目構(gòu)建工具(Maven或Gradle),你可以選擇相應(yīng)的方法添加依賴。
1.1. Maven
將以下依賴添加到項(xiàng)目的pom.xml
文件中:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.9</version> </dependency>
1.2. Gradle
將以下依賴添加到項(xiàng)目的build.gradle
文件中:
implementation 'com.google.code.gson:gson:2.8.9'
2. 創(chuàng)建Java對(duì)象模型
在項(xiàng)目中創(chuàng)建一個(gè)或多個(gè)Java類,用于表示JSON數(shù)據(jù)。例如,如果你要處理一個(gè)包含人員信息的JSON對(duì)象,你可以創(chuàng)建一個(gè)名為Person
的類:
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // 省略getter和setter方法 }
3. 使用Gson進(jìn)行序列化和反序列化
創(chuàng)建Gson實(shí)例并使用其提供的方法將Java對(duì)象轉(zhuǎn)換為JSON字符串(序列化)以及將JSON字符串轉(zhuǎn)換為Java對(duì)象(反序列化)。
3.1. 序列化
Person person = new Person("John Doe", 30); Gson gson = new Gson(); String json = gson.toJson(person); System.out.println(json);
3.2. 反序列化
String json = "{\"name\":\"John Doe\",\"age\":30}"; Gson gson = new Gson(); Person person = gson.fromJson(json, Person.class); System.out.println(person);
GsonBuilder詳解
excludeFieldsWithoutExposeAnnotation()
方法:
該方法用于設(shè)置 Gson 在序列化或反序列化時(shí),只包含帶有 @Expose
注解的字段。默認(rèn)情況下,Gson 包含所有字段,無(wú)論是否帶有 @Expose
注解。
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create();
excludeFieldsWithModifiers(Modifier... modifiers)
方法:
該方法用于設(shè)置 Gson 在序列化或反序列化時(shí),不包含指定修飾符的字段。參數(shù)為 Java 修飾符的可變參數(shù),表示不包含這些修飾符的字段不會(huì)被序列化或反序列化。
Gson gson = new GsonBuilder() .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT) .create();
serializeNulls()
方法:
該方法用于設(shè)置 Gson 在序列化時(shí),將 null 值作為字段的值進(jìn)行序列化。默認(rèn)情況下,Gson 不會(huì)將 null 值作為字段的值進(jìn)行序列化。
Gson gson = new GsonBuilder() .serializeNulls() .create();
disableHtmlEscaping()
方法:
該方法用于設(shè)置 Gson 在序列化時(shí),不對(duì) HTML 特殊字符進(jìn)行轉(zhuǎn)義。默認(rèn)情況下,Gson 會(huì)將 HTML 特殊字符(如 <
, >
等)進(jìn)行轉(zhuǎn)義。
Gson gson = new GsonBuilder() .disableHtmlEscaping() .create();
setPrettyPrinting()
方法:
該方法用于設(shè)置 Gson 在序列化時(shí),輸出格式化的 JSON 字符串。默認(rèn)情況下,Gson 輸出的 JSON 字符串是壓縮的。
Gson gson = new GsonBuilder() .setPrettyPrinting() .create();
setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy)
方法:
該方法用于設(shè)置 Gson 在序列化或反序列化時(shí),將 Java 字段名轉(zhuǎn)換為 JSON 字段名的策略。參數(shù)為一個(gè) FieldNamingStrategy 對(duì)象,表示轉(zhuǎn)換策略。
Gson gson = new GsonBuilder() .setFieldNamingStrategy(new FieldNamingStrategy() { @Override public String translateName(Field field) { return field.getName().toUpperCase(); } }) .create();
setDateFormat(String pattern)
方法:
該方法用于設(shè)置 Gson 在序列化或反序列化時(shí),使用的日期格式。參數(shù)為一個(gè)日期格式字符串。
Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd") .create();
registerTypeAdapter(Type type, Object typeAdapter)
方法:
該方法用于注冊(cè)一個(gè)自定義的 TypeAdapter 對(duì)象,用于在序列化或反序列化時(shí),轉(zhuǎn)換指定類型的對(duì)象。參數(shù)為需要轉(zhuǎn)換的 Java 類型和對(duì)應(yīng)的 TypeAdapter 對(duì)象。
Gson gson = new GsonBuilder()
registerTypeAdapterFactory(TypeAdapterFactory factory)
方法:
該方法用于注冊(cè)一個(gè)自定義的 TypeAdapterFactory 對(duì)象,用于在序列化或反序列化時(shí),轉(zhuǎn)換多個(gè)類型的對(duì)象。參數(shù)為需要轉(zhuǎn)換的 Java 類型工廠和對(duì)應(yīng)的 TypeAdapterFactory 對(duì)象。
Gson gson = new GsonBuilder() .registerTypeAdapterFactory(new MyTypeAdapterFactory()) .create();
registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter)
方法:
該方法用于注冊(cè)一個(gè)自定義的 TypeAdapter 對(duì)象,用于在序列化或反序列化時(shí),轉(zhuǎn)換指定基類的所有子類對(duì)象。參數(shù)為需要轉(zhuǎn)換的基類類型和對(duì)應(yīng)的 TypeAdapter 對(duì)象。
Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(Number.class, new MyNumberTypeAdapter()) .create();
setVersion(double version)
方法:
該方法用于設(shè)置 Gson 在序列化或反序列化時(shí),使用的版本號(hào)。默認(rèn)情況下,Gson 不使用版本號(hào)。
Gson gson = new GsonBuilder() .setVersion(1.0) .create();
enableComplexMapKeySerialization()
方法:
該方法用于設(shè)置 Gson 在序列化時(shí),支持序列化復(fù)雜的 Map 類型的鍵。默認(rèn)情況下,Gson 不支持序列化復(fù)雜的 Map 類型的鍵。
Gson gson = new GsonBuilder() .enableComplexMapKeySerialization() .create();
disableInnerClassSerialization()
方法:
該方法用于設(shè)置 Gson 在序列化時(shí),不序列化內(nèi)部類。默認(rèn)情況下,Gson 會(huì)序列化內(nèi)部類。
Gson gson = new GsonBuilder() .disableInnerClassSerialization() .create();
enableLongSerialization()
方法:
該方法用于設(shè)置 Gson 在序列化時(shí),將 long 類型的值強(qiáng)制轉(zhuǎn)換為字符串進(jìn)行序列化。默認(rèn)情況下,Gson 不會(huì)將 long 類型的值轉(zhuǎn)換為字符串。
Gson gson = new GsonBuilder() .enableLongSerialization() .create();
setFieldNamingPolicy(FieldNamingPolicy fieldNamingPolicy)
方法:
該方法用于設(shè)置 Gson 在序列化或反序列化時(shí),將 Java 字段名轉(zhuǎn)換為 JSON 字段名的策略。參數(shù)為一個(gè) FieldNamingPolicy 枚舉值,表示轉(zhuǎn)換策略。
Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) .create();
以上是 GsonBuilder
常用的方法,通過(guò)鏈?zhǔn)秸{(diào)用這些方法,可以靈活地配置 Gson 實(shí)例的行為。最后,調(diào)用 create()
方法可以創(chuàng)建一個(gè) Gson 實(shí)例。
高級(jí)特性
除了基本功能之外,Gson庫(kù)還提供了許多高級(jí)特性,以便在處理JSON數(shù)據(jù)時(shí)具有更大的靈活性。以下是Gson庫(kù)的一些高級(jí)特性:
1. 自定義序列化和反序列化
Gson庫(kù)提供了一些方法來(lái)允許開(kāi)發(fā)人員自定義Java對(duì)象的序列化和反序列化方式。例如,可以使用JsonSerializer
和JsonDeserializer
接口實(shí)現(xiàn)自定義序列化和反序列化。
1.1. 實(shí)現(xiàn)自定義序列化
public class PersonSerializer implements JsonSerializer<Person> { @Override public JsonElement serialize(Person person, Type type, JsonSerializationContext context) { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("name", person.getName()); jsonObject.addProperty("age", person.getAge()); return jsonObject; } }
1.2. 實(shí)現(xiàn)自定義反序列化
public class PersonDeserializer implements JsonDeserializer<Person> { @Override public Person deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = json.getAsJsonObject(); String name = jsonObject.get("name").getAsString(); int age = jsonObject.get("age").getAsInt(); return new Person(name, age); } }
1.3. 注冊(cè)自定義序列化和反序列化
GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Person.class, new PersonSerializer()); gsonBuilder.registerTypeAdapter(Person.class, new PersonDeserializer()); Gson gson = gsonBuilder.create();
2. 類型適配器
Gson庫(kù)提供了TypeAdapter
類,允許開(kāi)發(fā)人員完全控制序列化和反序列化的過(guò)程。
public class PersonTypeAdapter extends TypeAdapter<Person> { @Override public void write(JsonWriter out, Person person) throws IOException { out.beginObject(); out.name("name").value(person.getName()); out.name("age").value(person.getAge()); out.endObject(); } @Override public Person read(JsonReader in) throws IOException { in.beginObject(); String name = ""; int age = 0; while (in.hasNext()) { switch (in.nextName()) { case "name": name = in.nextString(); break; case "age": age = in.nextInt(); break; default: in.skipValue(); } } in.endObject(); return new Person(name, age); } }
3. JsonElement、JsonObject、JsonArray
Gson庫(kù)提供了一些類來(lái)動(dòng)態(tài)解析JSON數(shù)據(jù)。例如,可以使用JsonElement
、JsonObject
和JsonArray
類來(lái)訪問(wèn)JSON對(duì)象、JSON數(shù)組和JSON元素。
JsonElement element = JsonParser.parseString(json); if (element.isJsonObject()) { JsonObject jsonObject = element.getAsJsonObject(); // 訪問(wèn)JSON對(duì)象 } else if (element.isJsonArray()) { JsonArray jsonArray = element.getAsJsonArray(); // 訪問(wèn)JSON數(shù)組 } else if (element.isJsonPrimitive()) { JsonPrimitive jsonPrimitive = element.getAsJsonPrimitive(); // 訪問(wèn)JSON元素 }
4. 注解
Gson庫(kù)提供了一些注解,可以在Java對(duì)象的屬性上指定自定義名稱、排除某些屬性、指定版本等。
4.1. @SerializedName
使用@SerializedName
注解來(lái)指定Java對(duì)象屬性對(duì)應(yīng)的JSON屬性名。
public class Person { @SerializedName("full_name") private String name; private int age; //... }
4.2. @Expose
使用@Expose
注解來(lái)指定序列化和反序列化哪些屬性。
public class Person { @Expose private String name; @Expose(serialize = false) private int age; //... }
4.3. @Since 和 @Until
使用@Since
和@Until
注解來(lái)指定某些屬性在某個(gè)版本或版本之后才能夠被序列化或反序列化。
public class Person { @Since(1.0) private String name; @Until(2.0) private int age; //... }
5. 支持泛型
Gson庫(kù)支持處理泛型類型。例如,如果要將JSON數(shù)組轉(zhuǎn)換為泛型列表,可以使用TypeToken
類。
Type listType = new TypeToken<List<Person>>() {}.getType(); List<Person> personList = gson.fromJson(json, listType);
6. 對(duì)象引用處理
Gson庫(kù)可以正確地處理循環(huán)引用和對(duì)象引用。
public class Person { private String name; private int age; private List<Person> friends; //... }
如果某個(gè)人對(duì)象的朋友列表包含其他人對(duì)象,那么Gson可以正確地處理它們之間的引用。
通過(guò)這些高級(jí)特性,Gson庫(kù)提供了更多的選項(xiàng)和靈活性,可以滿足不同項(xiàng)目的需求和定制化需求。
總結(jié)
Gson是一個(gè)方便易用的Java JSON處理庫(kù),提供了一些簡(jiǎn)單易用的API來(lái)處理JSON數(shù)據(jù)。它具有許多有用的特性,如自定義序列化和反序列化、類型適配器、動(dòng)態(tài)解析JSON數(shù)據(jù)、注解支持、泛型支持等。使用Gson可以方便地將Java對(duì)象轉(zhuǎn)換為JSON格式的字符串,以及將JSON字符串轉(zhuǎn)換為等效的Java對(duì)象。
在使用Gson時(shí),需要注意以下一些優(yōu)勢(shì)和局限性:
優(yōu)勢(shì)
- 易于使用
- 性能相對(duì)較好
- 支持注解和泛型
局限性
- 無(wú)法處理復(fù)雜的嵌套關(guān)系
- 對(duì)于大型JSON文件,可能會(huì)占用較多內(nèi)存
在使用Gson時(shí),一些最佳實(shí)踐如下:
- 盡量使用JavaBean對(duì)象來(lái)表示JSON數(shù)據(jù)
- 避免使用循環(huán)引用
- 使用@Expose注解來(lái)控制屬性的序列化和反序列化
- 使用TypeToken處理泛型類型
- 避免將Gson對(duì)象作為全局對(duì)象,以避免線程安全問(wèn)題
最后,要注意保持Gson庫(kù)的版本更新,以獲取最新的功能和性能優(yōu)化。
到此這篇關(guān)于Java JSON處理庫(kù)之Gson的用法詳解的文章就介紹到這了,更多相關(guān)Java Gson內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springBoot 打war包 程序包c(diǎn)om.sun.istack.internal不存在的問(wèn)題及解決方案
這篇文章主要介紹了springBoot 打war包 程序包c(diǎn)om.sun.istack.internal不存在的問(wèn)題及解決方案,親測(cè)試過(guò)可以,需要的朋友可以參考下2018-07-07Java進(jìn)行Appium自動(dòng)化測(cè)試的實(shí)現(xiàn)
這篇文章主要介紹了Java進(jìn)行Appium自動(dòng)化測(cè)試的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01java網(wǎng)上圖書(shū)商城(5)購(gòu)物車(chē)模塊2
這篇文章主要為大家詳細(xì)介紹了java網(wǎng)上圖書(shū)商城,購(gòu)物車(chē)模塊第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12深入學(xué)習(xí)JAVA GC日志的相關(guān)知識(shí)
JVM 在Java應(yīng)用程序優(yōu)化中是不可缺少的一大重項(xiàng),如何合理配置Java參數(shù),如何驗(yàn)證配置參數(shù)的有效性,從GC日志中可以獲得很重要的提示。下面小編就帶大家來(lái)一起學(xué)習(xí)一下吧2019-06-06synchronized背后的monitor鎖實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了synchronized背后的monitor鎖實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Java實(shí)現(xiàn)計(jì)算圖中兩個(gè)頂點(diǎn)的所有路徑
這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)計(jì)算圖中兩個(gè)頂點(diǎn)的所有路徑功能,文中通過(guò)示例詳細(xì)講解了實(shí)現(xiàn)的方法,需要的可以參考一下2022-10-10Java使用IO流實(shí)現(xiàn)音頻的剪切和拼接
這篇文章主要為大家詳細(xì)介紹了Java使用IO流實(shí)現(xiàn)音頻的剪切和拼接,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06mybatis-plus的自動(dòng)填充時(shí)間的問(wèn)題(添加到數(shù)據(jù)庫(kù)的時(shí)間比當(dāng)前時(shí)間多4個(gè)小時(shí))
這篇文章主要介紹了mybatis-plus的自動(dòng)填充時(shí)間的問(wèn)題(添加到數(shù)據(jù)庫(kù)的時(shí)間比當(dāng)前時(shí)間多4個(gè)小時(shí)),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09jackson 如何將實(shí)體轉(zhuǎn)json json字符串轉(zhuǎn)實(shí)體
這篇文章主要介紹了jackson 實(shí)現(xiàn)將實(shí)體轉(zhuǎn)json json字符串轉(zhuǎn)實(shí)體,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10