提供一種像toString()和構造方法的很簡單的機制,來實現Java 對象和Json之間的互相轉換。html
容許已經存在的沒法改變的對象,轉換成Json,或者Json轉換成已存在的對象。json
容許自定義對象的表現形式api
支持任意的複雜對象數組
可以生成可壓縮和可讀的Json的字符串輸出。ide
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(局部類,能夠理解爲在方法內部聲明的類))的某個字段和外部類的某個字段同樣的話,就會被忽視,不會被序列化或者反序列化
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);
使用這個註解註釋的屬性,在json中,將會使用新的名字來進行對應
註解有兩個參數 value——對於序列化和反序列化都好使 alternate——只有反序列化好使
@SerializedName(value = "emailAddress", alternate = {"email", "email_address"}) public String emailAddress;
好比說,客戶端傳回來一張圖片,無論參數是img、imgine,我都能經過alternate參數來影射成POJO類中的對應的那個參數,很是的方便。
若是要處理數組類型很是的簡單:
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());
通常狀況下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的屬性也進行序列化