Gson(http://www.jianshu.com/p/e740196225a4)
- Serialization:序列化,使Java對象到Json字符串的過程。
- Deserialization:反序列化,字符串轉換成Java對象。
Gson解決的問題
-
提供一種像toString()和構造方法的很簡單的機制,來實現Java 對象和Json之間的互相轉換。
-
允許已經存在的無法改變的對象,轉換成Json,或者Json轉換成已存在的對象。
-
允許自定義對象的表現形式
-
支持任意的復雜對象
-
能夠生成可壓縮和可讀的Json的字符串輸出。
Gson處理對象的幾個重要點
1 推薦把成員變量都聲明稱private的
2 沒有必要用註解(@Expose 註解)指明某個字段是否會被序列化或者反序列化,所有包含在當前類(包括父類)中的字段都應該默認被序列化或者反序列化
3 如果某個字段被 transient 這個Java關鍵詞修飾,就不會被序列化或者反序列化
4 下面的實現方式能夠正確的處理null
1)當序列化的時候,如果對象的某個字段為null,是不會輸出到Json字符串中的。
2)當反序列化的時候,某個字段在Json字符串中找不到對應的值,就會被賦值為null
5 如果一個字段是 synthetic
的,他會被忽視,也即是不應該被序列化或者反序列化
6 內部類(或者anonymous class(匿名類),或者local class(局部類,可以理解為在方法內部聲明的類))的某個字段和外部類的某個字段一樣的話,就會被忽視,不會被序列化或者反序列化
Gson的基本用法
int i = gson.fromJson("100", int.class); String jsonNumber = gson.toJson(100); User user = new User("怪盜kidou",24); String jsonObject = gson.toJson(user); String jsonString = "{\"name\":\"怪盜kidou\",\"age\":24}"; User user = gson.fromJson(jsonString, User.class);
@SerializedName 註解重命名屬性
使用這個註解註釋的屬性,在json中,將會使用新的名字來進行對應
註解有兩個參數 value——對於序列化和反序列化都好使 alternate——只有反序列化好使
@SerializedName(value = "emailAddress", alternate = {"email", "email_address"}) public String emailAddress;
比如說,客戶端傳回來一張圖片,不管參數是img、imgine,我都能通過alternate參數來影射成POJO類中的對應的那個參數,非常的方便。
Gson中使用泛型
如果要處理數組類型非常的簡單:
Gson gson = new Gson(); String jsonArray = "[‘Android‘,‘Java‘,‘PHP‘]"; String[] strings = gson.fromJson(jsonArray, String[].class);
但是像要處理集合類就比較困難了,因為直接使用List<String>.class 得到的就是List的類,並不能知道裏面的泛型的類型
對於Java來說List<String>
和List<User>
這倆個的字節碼文件只一個那就是List.class
,這是Java泛型使用時要註意的問題 泛型擦除。
這裏就需要使用TypeToken來進行處理了
List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
GsonBuilder
一般情況下Gson
類提供的 API已經能滿足大部分的使用場景,但我們需要更多更特殊、更強大的功能時,這時候就引入一個新的類 GsonBuilder,這個類用於配置Gson的默認配置。
GsonBuilder用法
Gson gson = new GsonBuilder() //各種配置 .create(); //生成配置好的Gson
實際上是產生了Gson的實例,但是在中間增加了一些配置,只要的配置有:
1,Gson在默認情況下,是不會序列化值為null的鍵的。
Gson gson = new GsonBuilder().serializeNulls().create(); //這樣就會序列化值為null的鍵了
2,其他的配置
Gson gson = new GsonBuilder() //序列化null .serializeNulls() // 設置日期時間格式,另有2個重載方法 // 在序列化和反序化時均生效 .setDateFormat("yyyy-MM-dd") // 禁此序列化內部類 .disableInnerClassSerialization() //生成不可執行的Json(多了 )]}‘ 這4個字符) .generateNonExecutableJson() //禁止轉義html標簽 .disableHtmlEscaping() //格式化輸出 .setPrettyPrinting() .create();
字段過濾的幾種方法
1,@Expose註解
註解作用在屬性上,有兩個參數值 deserialize和serialize,默認為true,如果設置為false,那麽對應的字段就不會被序列化/反序列化
這裏實例化Gson的時候需要使用GsonBuilder
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create(); gson.toJson(category);
2,@Since
和 @Until註解
基於版本號,只有在某些版本上,字段才有效,使用GsonBuilder來進行版本的監控
new GsonBuilder().setVersion(1.2).create();
3,基於訪問修飾符
[email protected],只是排除了特定修飾符的方法。
Gson gson = new GsonBuilder() .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PRIVATE) .create();
4,基於策略,使用自定義的規則
//通過一個內部類,完成了自定義的字段的篩選,這裏是指定了反序列化的規則,還可以使用序列化函數指定序列化的規則
Gson g2=new GsonBuilder().addDeserializationExclusionStrategy(
new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { //返回true的就是要排除的,這裏是根據字段來排除 if ("name".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) { //返回true的就是要排除的,這裏是根據字段的類來排除 if(clazz.equals(int.class)) //直接排除了int型的屬性 return true; return false; } }).create();
一些簡單的例子:
Gson ggg=new GsonBuilder().setDateFormat("yyyy-mm-dd").serializeNulls().create();
設置了時間的格式,並且要求對於null的屬性也進行序列化
Gson(http://www.jianshu.com/p/e740196225a4)