亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

你真的會用Gson嗎?Gson使用指南(三)

2019-11-08 00:38:35
字體:
來源:轉載
供稿:網友

本文鏈接:http://www.jianshu.com/p/0e40a52c0063

JSON (官網) 是一種文本形式的數據交換格式,它比xml更輕量、比二進制容易閱讀和編寫,調式也更加方便。其重要性不言而喻。解析和生成的方式很多,java中最常用的類庫有:JSON-Java、Gson、Jackson、FastJson等。

該系列其它文章

你真的會用Gson嗎?Gson使用指南(一)你真的會用Gson嗎?Gson使用指南(二)你真的會用Gson嗎?Gson使用指南(三)你真的會用Gson嗎?Gson使用指南(四)

注:此系列基于Gson 2.4。

本次的主要內容:

字段過濾的幾種方法基于@Expose注解基于版本基于訪問修飾符基于策略(作者最常用)POJO與JSON的字段映射規則

一、字段過濾的幾種方法

字段過濾Gson中比較常用的技巧,特別是在Android中,在處理業務邏輯時可能需要在設置的POJO中加入一些字段,但顯然在序列化的過程中是不需要的,并且如果序列化還可能帶來一個問題就是 循環引用 ,那么在用Gson序列化之前為不防止這樣的事件情發生,你不得不作另外的處理。

以一個商品分類Category 為例。

{ "id": 1, "name": "電腦", "children": [ { "id": 100, "name": "筆記本" }, { "id": 101, "name": "臺式機" } ]}

一個大分類,可以有很多小分類,那么顯然我們在設計Category類時Category本身既可以是大分類,也可以是小分類。

public class Category { public int id; public String name; public List<Category> children;}

但是為了處理業務,我們還需要在子分類中保存父分類,最終會變成下面的情況

public class Category { public int id; public String name; public List<Category> children; //因業務需要增加,但并不需要序列化 public Category parent; }

但是上面的parent字段是因業務需要增加的,那么在序列化是并不需要,所以在序列化時就必須將其排除,那么在Gson中如何排除符合條件的字段呢?下面提供4種方法,大家可根據需要自行選擇合適的方式。

基于@Expose注解

@Expose提供了兩個屬性,且都有默認值,開發者可以根據需要設置不同的值。

@Expose

@Expose 注解從名字上就可以看出是暴露的意思,所以該注解是用于對處暴露字段的??墒俏覀円郧坝肎son的時候也沒有@Expose 注解還是不正確的序列化為JSON了么?是的,所以該注解在使用new Gson() 時是不會發生作用。畢竟最常用的API要最簡單,所以該注解必須和GsonBuilder配合使用。

使用方法: 簡單說來就是需要導出的字段上加上@Expose 注解,不導出的字段不加。注意是不導出的不加。

@Expose //@Expose(deserialize = true,serialize = true) //序列化和反序列化都都生效@Expose(deserialize = true,serialize = false) //反序列化時生效@Expose(deserialize = false,serialize = true) //序列化時生效@Expose(deserialize = false,serialize = false) // 和不寫一樣

注:根據上面的圖片可以得出,所有值為true的屬性都是可以不寫的。

拿上面的例子來說就是

public class Category { @Expose public int id; @Expose public String name; @Expose public List<Category> children; //不需要序列化,所以不加 @Expose 注解, //等價于 @Expose(deserialize = false,serialize = false) public Category parent; }

在使用Gson時也不能只是簡單的new Gson()了。

Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create();gson.toJson(category);
基于版本

Gson在對基于版本的字段導出提供了兩個注解 @Since 和 @Until,和GsonBuilder.setVersion(Double)配合使用。@Since 和 @Until都接收一個Double值。

Since和Until注解

使用方法:當前版本(GsonBuilder中設置的版本) 大于等于Since的值時該字段導出,小于Until的值時該該字段導出。

class SinceUntilSample { @Since(4) public String since; @Until(5) public String until;}public void sineUtilTest(double version){ SinceUntilSample sinceUntilSample = new SinceUntilSample(); sinceUntilSample.since = "since"; sinceUntilSample.until = "until"; Gson gson = new GsonBuilder().setVersion(version).create(); System.out.PRintln(gson.toJson(sinceUntilSample));}//當version <4時,結果:{"until":"until"}//當version >=4 && version <5時,結果:{"since":"since","until":"until"}//當version >=5時,結果:{"since":"since"}

注:當一個字段被同時注解時,需兩者同時滿足條件。

基于訪問修飾符

什么是修飾符? public、static 、final、private、protected 這些就是,所以這種方式也是比較特殊的。使用方式:

class ModifierSample { final String finalField = "final"; static String staticField = "static"; public String publicField = "public"; protected String protectedField = "protected"; String defaultField = "default"; private String privateField = "private";}

使用GsonBuilder.excludeFieldsWithModifiers構建gson,支持int形的可變參數,值由java.lang.reflect.Modifier提供,下面的程序排除了privateField 、 finalFieldstaticField 三個字段。

ModifierSample modifierSample = new ModifierSample();Gson gson = new GsonBuilder() .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PRIVATE) .create();System.out.println(gson.toJson(modifierSample));// 結果:{"publicField":"public","protectedField":"protected","defaultField":"default"}

到此為止,Gson提供的所有注解就還有一個@JsonAdapter沒有介紹了,而@JsonAdapter將和TypeAdapter將作為該系列第4篇也是最后一篇文章的主要內容。

基于策略(自定義規則)

上面介紹的了3種排除字段的方法,說實話我除了@Expose以外,其它的都是只在Demo用上過,用得最多的就是馬上要介紹的自定義規則,好處是功能強大、靈活,缺點是相比其它3種方法稍麻煩一點,但也僅僅只是想對其它3種稍麻煩一點而已。

基于策略是利用Gson提供的ExclusionStrategy接口,同樣需要使用GsonBuilder,相關API 2個,分別是addSerializationExclusionStrategy 和addDeserializationExclusionStrategy 分別針對序列化和反序化時。這里以序列化為例。

例如:

Gson gson = new GsonBuilder() .addSerializationExclusionStrategy(new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { // 這里作判斷,決定要不要排除該字段,return true為排除 if ("finalField".equals(f.getName())) return true; //按字段名排除 Expose expose = f.getAnnotation(Expose.class); if (expose != null && expose.deserialize() == false) return true; //按注解排除 return false; } @Override public boolean shouldSkipClass(Class<?> clazz) { // 直接排除某個類 ,return true為排除 return (clazz == int.class || clazz == Integer.class); } }) .create();

有沒有很強大?

二、 POJO與JSON的字段映射規則

之前在你真的會用Gson嗎?Gson使用指南(二) 屬性重命名時 介紹了@SerializedName這個注解的使用,本節的內容與上一次差不多的,但既然叫映射規則那么說的自然是有規律的情況。還是之前User的例子,已經去除所有注解:

User user = new User("怪盜kidou", 24);user.emailAddress = "ikidou@example.com";

GsonBuilder提供了FieldNamingStrategy接口和setFieldNamingPolicysetFieldNamingStrategy 兩個方法。

默認實現GsonBuilder.setFieldNamingPolicy 方法與Gson提供的另一個枚舉類FieldNamingPolicy配合使用,該枚舉類提供了5種實現方式分別為:

FieldNamingPolicy結果(僅輸出emailAddress字段)
IDENTITY{"emailAddress":"ikidou@example.com"}
LOWER_CASE_WITH_DASHES{"email-address":"ikidou@example.com"}
LOWER_CASE_WITH_UNDERSCORES{"email_address":"ikidou@example.com"}
UPPER_CAMEL_CASE{"EmailAddress":"ikidou@example.com"}
UPPER_CAMEL_CASE_WITH_SPACES{"Email Address":"ikidou@example.com"}

自定義實現GsonBuilder.setFieldNamingStrategy 方法需要與Gson提供的FieldNamingStrategy接口配合使用,用于實現將POJO的字段與JSON的字段相對應。上面的FieldNamingPolicy實際上也實現了FieldNamingStrategy接口,也就是說FieldNamingPolicy也可以使用setFieldNamingStrategy方法。

用法:

Gson gson = new GsonBuilder() .setFieldNamingStrategy(new FieldNamingStrategy() { @Override public String translateName(Field f) { //實現自己的規則 return null; } }) .create();

注意: @SerializedName注解擁有最高優先級,在加有@SerializedName注解的字段上FieldNamingStrategy不生效!

本文完


下期預告(本系列最終篇):
無所不能的TypeAdapter Android/Java開發


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品久久久久久久久久另类| 亚洲国产精品成人av| 91人人爽人人爽人人精88v| 91sa在线看| 久久久久久12| 国产亚洲人成网站在线观看| 欧美日韩在线视频一区二区| 日韩小视频在线| 日本高清视频一区| 亚洲精品一区在线观看香蕉| 欧美丝袜美女中出在线| 国产精品三级美女白浆呻吟| 亚洲人成电影网站| 国内偷自视频区视频综合| 国产日韩在线看片| 亚洲高清免费观看高清完整版| 国产伦精品一区二区三区精品视频| 欧美xxxx18性欧美| 亚洲男人天堂网站| 91久久精品国产91性色| 91精品久久久久久久久不口人| 欧美成人网在线| 亚洲人成77777在线观看网| 97视频在线观看成人| 免费av一区二区| 日韩中文视频免费在线观看| 成人国产精品免费视频| 国产一区二区av| 国产精品扒开腿做爽爽爽的视频| 精品久久久久久中文字幕一区奶水| 国产精品99导航| 国产在线视频2019最新视频| 国产一区二区三区精品久久久| 日韩电影视频免费| 91性高湖久久久久久久久_久久99| 欧美日韩亚洲视频一区| 久久99精品视频一区97| 精品综合久久久久久97| 国产亚洲精品激情久久| 欧洲精品久久久| 538国产精品视频一区二区| 国产精品久久久久久亚洲调教| 国产精品福利在线观看网址| 91精品视频在线看| 国产精品久久久久久久app| 国产亚洲欧美视频| 日韩中文字幕在线视频| 美日韩丰满少妇在线观看| 精品久久久久国产| 欧美成人在线网站| 亚洲www永久成人夜色| 精品女同一区二区三区在线播放| 成人深夜直播免费观看| 亚洲四色影视在线观看| 国产精品国产福利国产秒拍| 国产精品视频yy9099| 久久精品视频播放| 中文字幕在线看视频国产欧美| 欧美在线播放视频| 久久影视电视剧凤归四时歌| 国产一区视频在线播放| 国产日韩欧美在线| 欧美小视频在线| 亚洲国产美女精品久久久久∴| 欧美另类精品xxxx孕妇| 亚洲综合自拍一区| 欧美视频在线观看 亚洲欧| 九九热视频这里只有精品| 日本aⅴ大伊香蕉精品视频| 国产精品扒开腿爽爽爽视频| 中国人与牲禽动交精品| 国产成人综合亚洲| 国产香蕉一区二区三区在线视频| 久久久久久免费精品| 国产亚洲欧洲高清一区| 亚洲欧美在线免费观看| 91在线免费看网站| 欧美裸体xxxx极品少妇软件| 欧美视频在线观看 亚洲欧| 国产狼人综合免费视频| 日韩电影大全免费观看2023年上| 精品激情国产视频| 精品日韩中文字幕| 亚洲美腿欧美激情另类| 国产91精品久久久久久久| 国产精品海角社区在线观看| 97在线看免费观看视频在线观看| 国产精品www| 久久久久国产精品免费网站| 亚洲精品自拍第一页| 国产精品爱久久久久久久| 欧美性猛交xxx| 精品在线小视频| 亚洲成人性视频| 91久久精品久久国产性色也91| 成人网在线观看| 伊人一区二区三区久久精品| 日韩成人免费视频| 国产精品夜间视频香蕉| 亚洲最大成人免费视频| 久久在线观看视频| 日韩成人黄色av| 大胆人体色综合| 欧美性高潮在线| 亚洲国产精品一区二区三区| 88xx成人精品| 精品久久久久久久久久久| 高清欧美电影在线| 日韩免费不卡av| 538国产精品视频一区二区| 国产精品久久久久久av| 欧美日韩国产精品专区| 欧美福利在线观看| 亚洲午夜久久久久久久| 免费av一区二区| 久久精品夜夜夜夜夜久久| 亚洲aaa激情| 亚洲乱码国产乱码精品精天堂| 欧美性极品xxxx娇小| 成人欧美在线视频| 国产97在线亚洲| 色悠久久久久综合先锋影音下载| 久久久精品2019中文字幕神马| 国产精品自拍偷拍视频| 亚洲娇小xxxx欧美娇小| 精品性高朝久久久久久久| 亚洲热线99精品视频| 欧美与欧洲交xxxx免费观看| 亚洲国产一区自拍| 色综久久综合桃花网| 国产成人福利视频| 亚洲毛片在线观看| 国产91在线播放| 国产精品免费看久久久香蕉| 亚洲一级片在线看| 亚洲性69xxxbbb| 成人欧美在线观看| 日韩欧中文字幕| 欧美老少配视频| 91在线高清免费观看| 国产精品久久久久久久天堂| 国产99视频精品免视看7| 成人免费午夜电影| 97成人超碰免| 色中色综合影院手机版在线观看| 国产精品盗摄久久久| 国语自产精品视频在线看抢先版图片| 久久久精品国产亚洲| 中文一区二区视频| 91手机视频在线观看| 亚洲国产欧美一区二区三区久久| 日韩精品极品毛片系列视频| 亚洲免费高清视频| 中文字幕精品一区久久久久| 欧美一区二区影院| 91精品国产91久久久久福利| 正在播放亚洲1区| 国产一区二区三区中文| 亚洲福利视频专区| 一本大道香蕉久在线播放29| 国产成人a亚洲精品| 国产亚洲一区精品| 欧美一级免费视频| 精品久久久久久亚洲国产300|