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