在Android開發(fā)中,我們Android客戶端如果要和服務(wù)器端交互,一般都會采用json數(shù)據(jù)格式進(jìn)行交互,json對于大家來說都不陌生,本文講述一下關(guān)于gson,gson和其他現(xiàn)有java json類庫最大的不同時(shí)gson需要序列化得實(shí)體類不需要使用annotation來標(biāo)識需要序列化得字段,同時(shí)gson又可以通過使用annotation來靈活配置需要序列化的字段。

創(chuàng)新互聯(lián)專注于企業(yè)成都營銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、礦區(qū)網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、成都h5網(wǎng)站建設(shè)、商城系統(tǒng)網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為礦區(qū)等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
舉一個(gè)簡單的例子:
一個(gè)實(shí)體類 Person.java,參考代碼如下:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString()
{
return name + ":" +age;
}
}
這個(gè)類賦值,看看如何使用gson如何使用:
1.gson生成Json字符串
Gson gson = new Gson();//實(shí)例化gson
ListPerson persons = new ArrayListPerson();
for (int i = 0; i 10; i++) {
Person p = new Person();
p.setName("name" + i);
p.setAge(i * 5);
persons.add(p);
}
String str = gson.toJson(persons);//轉(zhuǎn)換json
說明:上面代碼主要說明gson的使用,它提供了toJason()方法將對象轉(zhuǎn)換成Json字符串,轉(zhuǎn)換出來就是很標(biāo)準(zhǔn)的json字符串.
2.gson如何將json字符串轉(zhuǎn)換成java實(shí)體類
Gson提供了fromJson()方法來實(shí)現(xiàn)從Json相關(guān)對象到j(luò)ava實(shí)體的方法。
日常應(yīng)用中,我們一般都會碰到兩種情況,轉(zhuǎn)成單一實(shí)體對象和轉(zhuǎn)換成對象列表或者其他結(jié)構(gòu)。
1)轉(zhuǎn)換單一java實(shí)體如何實(shí)現(xiàn)
比如json字符串為:[{"name":"張三","age":20}],那么轉(zhuǎn)換方式如下:
Person person = gson.fromJson(str, Person.class);
2)轉(zhuǎn)換成列表類型
比如json字符串為:[{"name":"張三","age":20},{"name":"李四","age":15},{"name":"王五","age":21}]
ListPerson ps = gson.fromJson(str, new TypeTokenListPerson(){}.getType());
for(int i = 0; i ps.size() ; i++)
{
Person p = ps.get(i);
System.out.println(p.toString());
}
說明:上面的代碼使用了TypeToken,它是gson提供的數(shù)據(jù)類型轉(zhuǎn)換器,可以支持各種數(shù)據(jù)集合類型轉(zhuǎn)換。
首先要導(dǎo)入Gson包;
例如有個(gè)penson類:
Gson gson = new Gson();
String json ;
person[] pers = gson. fromJson (json , person[].class);
首先先講一個(gè)比較簡單點(diǎn)的例子(最簡單的我就不講啦,網(wǎng)上很多),幫助新手理解Gson的使用方法:
比如我們要解析一個(gè)下面這種的Json:
String json = {"a":"100","b":[{"b1":"b_value1","b2":"b_value2"},{"b1":"b_value1","b2":"b_value2"}],"c":{"c1":"c_value1","c2":"c_value2"}}
首先我們需要定義一個(gè)序列化的Bean,這里采用內(nèi)部類的形式,看起來會比較清晰一些:
public class JsonBean {
public String a;
public ListB b;
public C c;
public static class B {
public String b1;
public String b2;
}
public static class C {
public String c1;
public String c2;
}
}
很多時(shí)候大家都是不知道這個(gè)Bean是該怎么定義,這里面需要注意幾點(diǎn):
1、內(nèi)部嵌套的類必須是static的,要不然解析會出錯(cuò);
2、類里面的屬性名必須跟Json字段里面的Key是一模一樣的;
3、內(nèi)部嵌套的用[]括起來的部分是一個(gè)List,所以定義為 public ListB b,而只用{}嵌套的就定義為 public C c,
具體的大家對照J(rèn)son字符串看看就明白了,不明白的我們可以互相交流,本人也是開發(fā)新手!
Gson gson = new Gson();
java.lang.reflect.Type type = new TypeTokenJsonBean() {}.getType();
JsonBean jsonBean = gson.fromJson(json, type);
然后想拿數(shù)據(jù)就很簡單啦,直接在jsonBean里面取就可以了!
如果需要解析的Json嵌套了很多層,同樣可以可以定義一個(gè)嵌套很多層內(nèi)部類的Bean,需要細(xì)心的對照J(rèn)son字段來定義哦。
Json 是一種文本形式的數(shù)據(jù)交換格式,比 xml 更為輕量。Json 的解析和生成的方式很多,在 Android 平臺上最常用的類庫有 Gson 和 FastJson 兩種,這里要介紹的是 Gson
Gson 的 GitHub 主頁點(diǎn)擊這里: Gson
在進(jìn)行序列化與反序列操作前,需要先實(shí)例化一個(gè) com .google.gson.Gson 對象,獲取 Gson 對象的方法有兩種
利用 Gson 可以很方便地生成 Json 字符串,通過使用 addProperty 的四個(gè)重載方法
addProperty 方法底層調(diào)用的是 add(String property, JsonElement value) 方法,即將基本數(shù)據(jù)類型轉(zhuǎn)化為了 JsonElement 對象,JsonElement 是一個(gè)抽象類,而 JsonObject 繼承了 JsonElement ,因此我們可以通過 JsonObject 自己來構(gòu)建一個(gè) JsonElement
Json數(shù)組 與 字符串?dāng)?shù)組
Json數(shù)組 與 List
Gson 也提供了 toJson() 和 fromJson() 兩個(gè)方法用于轉(zhuǎn)化 Model 與 Json,前者實(shí)現(xiàn)了序列化,后者實(shí)現(xiàn)了反序列化
首先,聲明一個(gè) User 類
序列化的方法很簡單,調(diào)用 gson 對象的 toJson 方法,傳入要序列化的對象
反序化的方式也類似
繼續(xù)使用上一節(jié)聲明的 User 類,根據(jù) User 類聲明的各個(gè)屬性名,移動(dòng)端的開發(fā)者希望接口返回的數(shù)據(jù)格式即是如下這樣的
如果沒有和服務(wù)器端溝通好或者是 API 改版了,接口返回的數(shù)據(jù)格式可能是這樣的
如果繼續(xù)使用上一節(jié)介紹的方法,那無疑會解析出錯(cuò)
例如
name 屬性值解析不到,所以為 null
此時(shí)為了兼顧多種格式的數(shù)據(jù),就需要使用 SerializedName 注解
根據(jù) SerializedName 的聲明來看,SerializedName 包含兩個(gè)屬性值,一個(gè)是字符串,一個(gè)是字符串?dāng)?shù)組,而字符串?dāng)?shù)組含有默認(rèn)值
SerializedName 的作用是為了在序列化或反序列化時(shí),指導(dǎo) Gson 如果將原有的屬性名和其它特殊情況下的屬性名聯(lián)系起來
例如,修改 User 類,為 name 聲明 SerializedName 注解,注解值為 userName
在序列時(shí),Json 格式就會相應(yīng)改變
在反序列化時(shí)也一樣,能夠解析到正確的屬性值
還有個(gè)問題沒解決,為了應(yīng)對多種屬性名不一致的情況,難道我們要聲明多個(gè) User 類嗎?這顯然是不現(xiàn)實(shí)的,所以還需要為 User 類設(shè)置多個(gè)備選屬性名,這就需要用到 SerializedName 注解的另一個(gè)屬性值 alternate 了。
以下幾種情況都能夠被正確的反序列化
有時(shí)候并不是所有的字段都需要進(jìn)行系列化和反序列化,因此需要對某些字段進(jìn)行排除,有四種方法可以來實(shí)現(xiàn)這種需求。
Expose 注解包含兩個(gè)屬性值,且均聲明了默認(rèn)值。Expose 的含義即為“暴露”,即用于對外暴露字段,serialize 用于指定是否進(jìn)行序列化,deserialize 用于指定是否進(jìn)行反序列化。如果字段不聲明 Expose 注解,則意味著不進(jìn)行序列化和反序列化操作,相當(dāng)于兩個(gè)屬性值均為 false 。此外,Expose 注解需要和 GsonBuilder 構(gòu)建的 Gson 對象一起使用才能生效。
Expose 注解的注解值聲明情況有四種
現(xiàn)在來看個(gè)例子,修改 User 類
按照如上的注解值,只有聲明了 Expose 注解且 serialize 值為 true 的字段才能被序列化,只有聲明了 Expose 注解且 deserialize 值為 true 的字段才能被反序列化
Gson 提供了 @Since 和 @Until 兩個(gè)注解基于版本對字段進(jìn)行過濾,@Since 和 @Until 都包含一個(gè) Double 屬性值,用于設(shè)置版本號。Since 的意思是“自……開始”,Until 的意思是“到……為止”,一樣要和 GsonBuilder 配合使用。
當(dāng)版本( GsonBuilder 設(shè)置的版本) 大于或等于 Since 屬性值或小于 Until 屬性值時(shí)字段會進(jìn)行序列化和反序列化操作,而沒有聲明注解的字段都會加入序列化和反序列操作
現(xiàn)在來看個(gè)例子,修改 User 類
訪問修飾符由 java.lang.reflect.Modifier 提供 int 類型的定義,而 GsonBuilder 對象的 excludeFieldsWithModifiers 方法接收一個(gè) int 類型可變參數(shù),指定不進(jìn)行序列化和反序列化操作的訪問修飾符字段
看個(gè)例子
GsonBuilder 類包含 setExclusionStrategies(ExclusionStrategy... strategies) 方法用于傳入不定長參數(shù)的策略方法,用于直接排除指定字段名或者指定字段類型
看個(gè)例子
字段名為 "intField" 和字段類型為 double 的字段都會被排除掉
setExclusionStrategies 方法在序列化和反序列化時(shí)都會生效,如果只是想指定其中一種情況下的排除策略或分別指定排除策略,可以改為使用以下兩個(gè)方法
對于 Gson 而言,在序列化時(shí)如果某個(gè)屬性值為 null 的話,那么在序列化時(shí)該字段不會參與進(jìn)來,如果想要顯示輸出該字段的話,可以通過 GsonBuilder 進(jìn)行配置
默認(rèn)的序列化后的 Josn 字符串并不太直觀,可以選擇格式化輸出
Gson 也可以對時(shí)間值進(jìn)行格式化
TypeAdapter 是一個(gè)泛型抽象類,用于接管某種類型的序列化和反序列化過程,包含兩個(gè)抽象方法,分別用于自定義序列化和反序列化過程
下面看個(gè)簡單的例子
定義 TypeAdapter 的子類 UserTypeAdapter 來接管 User 類的序列化和反序列化過程
這里設(shè)定當(dāng) User 類序列化時(shí) Json 中的Key值都是大寫字母開頭,反序列化時(shí)支持“name”和“Name”兩種不同的 Json 風(fēng)格
可以看到 User 類按照預(yù)定義的策略來完成序列化和反序列化了
TypeAdapter 將序列化和反序列操作都接管了過來,其實(shí) Gson 還提供了只接管序列化過程的接口,即 JsonSerializer
看個(gè)例子
相對應(yīng)的,JsonDeserializer 接口提供了反序列化的接口
這里有個(gè)比較麻煩的地方,那就是在使用 TypeAdapter 、JsonSerializer 和 JsonDeserializer 時(shí),總需要調(diào)用 registerTypeAdapter 方法進(jìn)行注冊,那有沒有更簡單的注冊方法呢?
有的,Gosn 還提供了另一個(gè)注解 @JsonAdapter 用于進(jìn)行簡單的聲明
類似于這樣,聲明了 User 類的序列化或反序列化操作由 UserTypeAdapter 完成,注解的優(yōu)先級高于 registerTypeAdapter 方法
TypeAdapterFactory 是用于創(chuàng)建 TypeAdapter 的工廠類,通過參數(shù) TypeToken 來查找確定對應(yīng)的 TypeAdapter,如果沒有就返回 null 并由 Gson 默認(rèn)的處理方法來進(jìn)行序列化和反序列化操作,否則就由用戶預(yù)定義的 TypeAdapter 來進(jìn)行處理
這一篇文章好像寫得太長了一點(diǎn)?Gson 的知識點(diǎn)介紹到這里也差不多了,以后如果還發(fā)現(xiàn)新內(nèi)容的話我會繼續(xù)補(bǔ)充,現(xiàn)在就先這樣啦
Gson挺好用的,可以把json串直接解析成bean對象,或者把對象轉(zhuǎn)換成json串,數(shù)據(jù)解析的時(shí)候先創(chuàng)建Gson對象
Gson?mGson?=?new?Gson();
然后再把json串解析成bean對象
Bean?bean?=?mGson.fromJson(json,?Bean.class);
如果想把對象轉(zhuǎn)成json串可以用gson的toJson方法
String?json?=?mGson.toJson();
純手打,滿意請采納
Android存儲文件通常可以用SharedPreferences、SQLite、Content Provider和File,但是SharedPreferences只支持簡單的key-value,
通常,如果要存儲一個(gè)對象,可以先把它序列化,然后用輸入輸出流存進(jìn)file文件
另一個(gè)我比較喜歡的方式是:
寫:先把一個(gè)對象用gson解析成json字符串(使用gson的toJson函數(shù)),然后當(dāng)成一個(gè)value寫進(jìn)SharedPreferences里面
讀:讀取出來的時(shí)候就再次用gson把json解析成對象(使用gson的fromJson函數(shù))
參考:
Android中的JSON詳細(xì)總結(jié)
怎樣使用Gson 解析 (deserialize) json字符串
Gson簡要使用筆記
代碼實(shí)現(xiàn):
新聞標(biāo)題:關(guān)于gsonandroid的信息
鏈接地址:http://chinadenli.net/article13/dsgjigs.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、軟件開發(fā)、網(wǎng)站策劃、定制網(wǎng)站、企業(yè)建站、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)