java gson_Java 中 Gson的使用

JSON 是一種文本形式的數據交換格式,它比XML更輕量、比二進制容易閱讀和編寫,調式也更加方便;解析和生成的方式很多,Java中最常用的類庫有:JSON-Java、Gson、Jackson、FastJson等

一、Gson的基本用法

Gson提供了fromJson() 和toJson() 兩個直接用于解析和生成的方法,前者實現反序列化,后者實現了序列化;同時每個方法都提供了重載方法

(1)基本數據類型的解析

Gson gson = new Gson();

int i = gson.fromJson("100", int.class); //100

double d = gson.fromJson("\"99.99\"", double.class); //99.99

boolean b = gson.fromJson("true", boolean.class); // true

String str = gson.fromJson("String", String.class); // String

(2)基本數據類型的生成

Gson gson = new Gson();

String jsonNumber = gson.toJson(100); // 100

String jsonBoolean = gson.toJson(false); // false

String jsonString = gson.toJson("String"); //"String"

(3)POJO類的生成與解析

public class User {

//省略其它

public String name;

public int age;

public String emailAddress;

}

生成JSON:

Gson gson = new Gson();

User user = new User("張三",24);

String jsonObject = gson.toJson(user); // {"name":"張三kidou","age":24}

解析JSON:

Gson gson = new Gson();

String jsonString = "{\"name\":\"張三\",\"age\":24}";

User user = gson.fromJson(jsonString, User.class);

二、屬性重命名 @SerializedName 注解的使用

從上面POJO的生成與解析可以看出json的字段和值是的名稱和類型是一一對應的,但也有一定容錯機制(如第一個例子第3行將字符串的99.99轉成double型),但有時候也會出現一些不和諧的情況,如:

期望的json格式:{"name":"張三","age":24,"emailAddress":"zhangsan@ceshi.com"}

實際:{"name":"張三","age":24,"email_address":"zhangsan@ceshi.com"}

Gson在序列化和反序列化時需要使用反射,一般各類庫都將注解放到annotations包下,打開源碼在com.google.gson包下有一個annotations,里面有一個SerializedName的注解類。對于json中email_address這個屬性對應POJO的屬性則變成:

@SerializedName("email_address")

public String emailAddress;

為POJO字段提供備選屬性名:SerializedName注解提供了兩個屬性,上面用到了其中一個,別外還有一個屬性alternate,接收一個String數組

注:alternate需要2.4版本

48304ba5e6f9fe08f3fa1abda7d326ab.png

@SerializedName(value = "emailAddress", alternate = {"email", "email_address"})

public String emailAddress;

//當三個屬性(email_address、email、emailAddress)都中出現任意一個時均可以得到正確的結果

//當多種情況同時出時,以最后一個出現的值為準。

Gson gson = new Gson();

String json = "{\"name\":\"張三kidou\",\"age\":24,\"emailAddress\":\"zhangsan@ceshi.com\",\"email\":\"zhangsan_2@ceshi.com\",\"email_address\":\"zhangsan_3@ceshi.com\"}";

User user = gson.fromJson(json, User.class);

System.out.println(user.emailAddress); // zhangsan_3@example.com

48304ba5e6f9fe08f3fa1abda7d326ab.png

三、Gson中使用泛型

例如:JSON字符串數組:["Android","Java","PHP"]

當要通過Gson解析這個json時,一般有兩種方式:使用數組,使用List;而List對于增刪都是比較方便的,所以實際使用是還是List比較多

數組比較簡單:

Gson gson = new Gson();

String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";

String[] strings = gson.fromJson(jsonArray, String[].class);

對于List將上面的代碼中的 String[].class 直接改為 List.class 是不行的,對于Java來說List 和List 這倆個的字節碼文件只一個那就是List.class,這是Java泛型使用時要注意的問題 泛型擦除

為了解決的上面的問題,Gson提供了TypeToken來實現對泛型的支持,所以將以上的數據解析為List時需要這樣寫

Gson gson = new Gson();

String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";

String[] strings = gson.fromJson(jsonArray, String[].class);

List stringList = gson.fromJson(jsonArray, new TypeToken>() {}.getType());

//TypeToken的構造方法是protected修飾的,所以上面才會寫成new TypeToken>() {}.getType() 而不是 new TypeToken>().getType()

泛型解析對接口POJO的設計影響

泛型的引入可以減少無關的代碼:

{"code":"0","message":"success","data":{}}

{"code":"0","message":"success","data":[]}

我們真正需要的data所包含的數據,而code只使用一次,message則幾乎不用,如果Gson不支持泛型或不知道Gson支持泛型的同學一定會這么定義POJO

public class UserResponse {

public int code;

public String message;

public User data;

}

當其它接口的時候又重新定義一個XXResponse將data的類型改成XX,很明顯code,和message被重復定義了多次,通過泛型可以將code和message字段抽取到一個Result的類中,這樣只需要編寫data字段所對應的POJO即可:

public class Result {

public int code;

public String message;

public T data;

}

//對于data字段是User時則可以寫為 Result ,當是個列表的時候為 Result>

四、Gson的流式反序列化

(1)自動方式

Gson提供了fromJson()和toJson() 兩個直接用于解析和生成的方法,前者實現反序列化,后者實現了序列化。同時每個方法都提供了重載方法

Gson.toJson(Object);

Gson.fromJson(Reader,Class);

Gson.fromJson(String,Class);

Gson.fromJson(Reader,Type);

Gson.fromJson(String,Type);

(2)手動方式:手動的方式就是使用stream包下的JsonReader類來手動實現反序列化,和Android中使用pull解析XML是比較類似的

48304ba5e6f9fe08f3fa1abda7d326ab.png

String json = "{\"name\":\"張三\",\"age\":\"24\"}";

User user = new User();

JsonReader reader = new JsonReader(new StringReader(json));

reader.beginObject();

while (reader.hasNext()) {

String s = reader.nextName();

switch (s) {

case "name":

user.name = reader.nextString();

break;

case "age":

user.age = reader.nextInt(); //自動轉換

break;

case "email":

user.email = reader.nextString();

break;

}

}

reader.endObject(); // throws IOException

System.out.println(user.name); //張三

System.out.println(user.age); // 24

System.out.println(user.email); //zhangsan@ceshi.com

48304ba5e6f9fe08f3fa1abda7d326ab.png

自動方式最終都是通過JsonReader來實現的,如果第一個參數是String類型,那么Gson會創建一個StringReader轉換成流操作

fd463113dc97c6dcf2169ce5f1900d14.png

五、Gson的流式序列化

(1)自動方式

7380417118fdbbc848ee482a06358f14.png

Gson.toJson方法列表

//PrintStream(System.out) 、StringBuilder、StringBuffer和*Writer都實現了Appendable接口。

Gson gson = new Gson();

User user = new User("張三",24,"zhangsan@ceshi.com");

gson.toJson(user,System.out);

(2)手動方式

48304ba5e6f9fe08f3fa1abda7d326ab.png

JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));

writer.beginObject() // throws IOException

.name("name").value("張三")

.name("age").value(24)

.name("email").nullValue() //演示null

.endObject(); // throws IOException

writer.flush(); // throws IOException

//{"name":"張三","age":24,"email":null}

//除了beginObject、endObject還有beginArray和endArray,兩者可以相互嵌套,注意配對即可。beginArray后不可以調用name方法,同樣beginObject后在調用value之前必須要調用name方法。

48304ba5e6f9fe08f3fa1abda7d326ab.png

六、 使用GsonBuilder導出null值、格式化輸出、日期時間

一般情況下Gson類提供的 API已經能滿足大部分的使用場景,但有時需要更多特殊、強大的功能時,這時候就引入一個新的類 GsonBuilder。

GsonBuilder從名上也能知道是用于構建Gson實例的一個類,要想改變Gson默認的設置必須使用該類配置Gson

GsonBuilder用法:

//各種配置 //生成配置好的Gson

Gson gson = new GsonBuilder().create();

(1)Gson在默認情況下是不動導出值null的鍵的,如:

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class User {

public String name;

public int age;

//省略

public String email;

}

Gson gson = new Gson();

User user = new User(張三",24);

System.out.println(gson.toJson(user)); //{"name":"張三","age":24}

//email字段是沒有在json中出現的,當在調試時需要導出完整的json串時或API接中要求沒有值必須用Null時,就會比較有用。

48304ba5e6f9fe08f3fa1abda7d326ab.png

使用方法:

Gson gson = new GsonBuilder().serializeNulls() .create();

User user = new User("張三", 24);

System.out.println(gson.toJson(user)); //{"name":"張三","age":24,"email":null}

格式化輸出、日期時間及其它:

48304ba5e6f9fe08f3fa1abda7d326ab.png

Gson gson = new GsonBuilder()

//序列化null

.serializeNulls()

// 設置日期時間格式,另有2個重載方法

// 在序列化和反序化時均生效

.setDateFormat("yyyy-MM-dd")

// 禁此序列化內部類

.disableInnerClassSerialization()

//生成不可執行的Json(多了 )]}' 這4個字符)

.generateNonExecutableJson()

//禁止轉義html標簽

.disableHtmlEscaping()

//格式化輸出

.setPrettyPrinting()

.create();

//:內部類(Inner Class)和嵌套類(Nested Class)的區別

48304ba5e6f9fe08f3fa1abda7d326ab.png

原文 :?https://www.cnblogs.com/qinxu/p/9504412.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529986.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529986.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529986.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

spring注入普通java類_普通java類如何取得注入spring Ioc容器的對象

[除了使用XML配置外,還可以選擇使用基于注解(annotation)的配置方式,其依賴于字節碼來織入組件。注解注入在XML注入之前完成,因此在XML配置中可以重載注解注入的屬性。一、建一個SpringUtil類package com.ceopen.eoss.spring; import org.spr…

java web 集成dom4j_[JavaWeb基礎] 031.dom4j寫入xml的方法

上一篇我們講述了dom4j讀取xml的4種方法,甚是精彩,那么怎么樣寫入xml呢?我們直接看下源碼實現。public static void main(String[] args) throws Exception {// 創建文檔Document document DocumentHelper.createDocument();// 設置編碼docu…

java servlet 調試日志 logger sae_java servlet 調試日志 lo

java servlet 調試日志 lo[2021-02-10 08:32:08] 簡介:php去除nbsp的方法:首先創建一個PHP代碼示例文件;然后通過“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推薦&#x…

java接口權限管理在哪里_java訪問權限控制

為什么java要有訪問權限的控制?訪問權限的設置和代碼的重構有關。在一個項目中,大多數的時間和金錢都投入到了代碼的維護當中。維護中一定會修改已存在的不合理的代碼。但是在重構的過程中,就出現了這樣的問題:如何保證不影響那些使用了待修…

java8 stream index_Java8的stream用法整理

/***authorindex* date 2020/10/27**/public classTestcollectingAndThen {Testpublic voidtest(){final int NUM 14;List peopleList new ArrayList<>(NUM);String[] names {"小張", "小龍", "小牛", "小豬", "小黑&quo…

memo、 useMemo 和 useCallback語法講解

memo、 useMemo 和 useCallback 緩存組件, 對組件淺比較 (只有組件的props, (對函數,引用要用useCallback包裹)發生變化 緩存值, 依賴項變化&#xff0c;會從新計算。 緩存函數, 依賴項變化,重新生成新函數 useMemo 語法 對返回的值緩存進行優化 const memoizedValue useMem…

java只修改變的字段_java注解之運行時修改字段的注解值操作

今天遇到需求&#xff1a;導入Excel時候列頭會發生變化&#xff0c;客戶是大爺要求你改代碼&#xff0c;導入Excel是用easypoi做的&#xff0c;識別表頭是用注解Excel(name "xxx")通過這個name來匹配那你表頭要動&#xff0c;我這個注解是硬編碼所以就有動態設置這個…

求java簡單計算器源代碼_java簡單計算器源代碼

簡單計算器代碼package calcultorthree;import java.awt.BorderLayout;//導入邊界布局管理器類import java.awt.GridLayout;//導入網格布局管理器類import java.awt.TextField;//導入文本區域類import java.awt.event.ActionEvent;//導入事件類import java.awt.event.ActionLis…

java中間語言匯編語言_中間語言(IL) | 學步園

一、IL與匯編語言IL是微軟.NET平臺上衍生出的一門中間語言&#xff0c;.NET平臺上的各種高級語言(如C#&#xff0c;VB&#xff0c;F#)的編譯器會將各自的代碼轉化為IL。&#xff0c;其中包含了.NET平臺上的各種元素&#xff0c;如“范型”&#xff0c;“類”、、“接口”、“模…

java遍歷斐波納契數列_詳解循環、迭代、遞歸、分治(Leet Code 509 斐波那契數列),實際運用...

Multiple solutions of Fibonacci (Python or Java)本章是用英文寫的&#xff0c;作為或想成為一名優秀的攻城獅&#xff0c;習慣閱讀英文文檔將使你受益良多。例如更好的查看最新版的官方文檔、與國外友人交流、等等 其實英文的生詞也并不多,其中90&#xff05;的英文都在代碼…

java棧內存是先進后出嗎_java堆內存與棧內存區別

棧(stack):是一個先進后出的數據結構,通常用于保存方法(函數)中的參數,局部變量. 在java中,所有基本類型和引用類型都在棧中存儲.棧中數據的生存空間一般在當前scopes內(就是由{...}括起來的區域).棧的優勢是&#xff0c;存取速度比堆要快&#xff0c;僅次于直接位于CPU中的寄存…

主頁面功能的java_6-04-項目實戰-主頁面顯示當前用戶退出功能實現

教程列表&#xff1a;1-01-servlet學習-HTTP協議的概念作用和特點1-02-servlet學習-HTTP協議的交互流程和請求格式和請求方式1-03-servlet學習-HTTP協議的響應格式和常見狀態碼1-04-servlet學習-服務器介紹&tomcat服務器的安裝和驗證1-05-servlet學習-第一個web項目1-06-se…

java 二分查找 排序_java 冒泡排序 二分查找

下面這個程序是先定義一個整型數組&#xff0c;然后將其中的元素反序賦值&#xff0c;再用冒泡排序進行排序以后用二分查找來查找其中是否有某個數&#xff0c;返回值為-1時表示這個數可能小于這個數組的最小值或大小這個數組的最大值&#xff0c;-2表示這個數比這個數組的最小…

php 數組設置為空,PHP數組設置空值

如果沒有數據存在&#xff0c;如何將數組值設置為null&#xff1f;PHP數組設置空值以下是我的PHP陣列和我JSON編碼 -{"title":"Impalz-Marketing","type":"Business Details","version":"1.0","login":…

什么是寫一個java類,Java什么是類?class的相關介紹

本章給大家帶來Java什么是類&#xff1f;class的相關介紹&#xff0c;讓大家了解關于類(class)的一些知識。有一定的參考價值&#xff0c;有需要的朋友可以參考一下&#xff0c;希望對你有所幫助。class Point{constructor(){}toString(){}}console.log(Object.keys(Point.prot…

windows php sqlite,如何在Apache 2.4(Windows 7)上為PHP 5.6.14配置SQLite3?

我在Windows 7上,在Apache 2.4上使用PHP 5.6.14版,我正在嘗試訪問SQLite3數據庫.我正在……致命錯誤&#xff1a;找不到類“SQLite3”在這里你是一個簡單的PHP代碼…$db new SQLite3(phpdb);if ($db) {$db->query("CREATE TABLE dogbreeds (Name VARCHAR(255), MaxAge…

php 國密 簽名,關于php國密SM3簽名算法

推薦&#xff1a;《PHP視頻教程》php國密SM3簽名算法代碼地址github.com/lizhichao/sm安裝composer require lizhichao/one-sm使用require __DIR__ . /vendor/autoload.php; // 字符串簽名 echo OneSmSm3::sign(abc) . PHP_EOL; echo OneSmSm3::sign(str_repeat("adfas哈哈…

matlab狀態方程 傳遞函數 可控性,實驗一matlab系統的傳遞函數和狀態空間表達式的轉換...

實驗一 MATLAB 系統的傳遞函數和狀態空間表達式的轉換一、 實驗目的1、學習多變量系統狀態空間表達式的建立方法&#xff1b;2、通過編程、上機調試&#xff0c;掌握多變量系統狀態空間表達式與傳遞函數之間相互轉換的方法&#xff1b;3、掌握相應的MATLAB 函數。二、 實驗原理…

php里h和h的區別嗎,編碼h264h和h264b有什么區別

區別如下&#xff1a;1、版本H.265是新的編碼協議&#xff0c;也即是H.264的升級版。H.265標準保留H.264原來的某些技術&#xff0c;同時對一些相關的技術加以改進。新技術使用先進的技術用以改善碼流、編碼質量、延時和算法復雜度之間的關系&#xff0c;達到最優化設置。2、儲…

mysql5.1怎么備份,MySQL 5.1升級到MySQL 5.5的步驟

mysql 5.5已經出來有一段時間&#xff0c;性能有明顯提升&#xff0c;特別是對多核CPU的支持與TPS性能的提升。上周博主介紹了linux下編譯安裝mysql 5.5的步驟&#xff0c;安裝不出意外基本沒有問題。不過可能很多朋友和我一樣一直用的是mysql 5.1&#xff0c;現在想把數據庫升…