Gson(http://www.jianshu.com/p/e740196225a4)

  • Serialization:序列化,使Java對象到Json字符串的過程。
  • Deserialization:反序列化,字符串轉換成Java對象。

Gson解決的問題

  1. 提供一種像toString()和構造方法的很簡單的機制,來實現Java 對象和Json之間的互相轉換。html

  2. 容許已經存在的沒法改變的對象,轉換成Json,或者Json轉換成已存在的對象。json

  3. 容許自定義對象的表現形式api

  4. 支持任意的複雜對象數組

  5. 可以生成可壓縮和可讀的Json的字符串輸出。ide


Gson處理對象的幾個重要點

1 推薦把成員變量都聲明稱private的函數

2 沒有必要用註解(@Expose 註解)指明某個字段是否會被序列化或者反序列化,全部包含在當前類(包括父類)中的字段都應該默認被序列化或者反序列化ui

3 若是某個字段被 transient 這個Java關鍵詞修飾,就不會被序列化或者反序列化spa

4 下面的實現方式可以正確的處理null
1)當序列化的時候,若是對象的某個字段爲null,是不會輸出到Json字符串中的。
2)當反序列化的時候,某個字段在Json字符串中找不到對應的值,就會被賦值爲nullcode

5 若是一個字段是 synthetic
的,他會被忽視,也便是不該該被序列化或者反序列化orm

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,基於訪問修飾符

這個跟基於@Expose的很相似,只是排除了特定修飾符的方法。

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的屬性也進行序列化

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息