Android網絡資料解析之Gson
一、Gson解析架構
Gson由谷歌研發,可以把Java對象轉成Json,也可以把Json字元串轉換成一個相等的Java對象。Gson支援任意複雜Java對象包括沒有源代碼的對象。
注:
Gson序列化的時候,如果對象的某個字段為null,是不會輸出到Json中的。
Gson反序列化的時候,如果某個字段在Json中找不到對應的值,就會被指派為null。
不會被序列化和反序列化字段:transient、synthetic、内部類的某個字段和外部類的某個字段一樣。
二、Gson基本用法
在build.gradle中配置:compile ‘com.google.code.gson:gson:2.4’
Gson提供了fromJson()和toJson()兩個直接用于解析和生成的方法,fromJson()實作反序列化,toJson()實作序列化。同時每個方法都提供了重載方法。
1. 基本資料類型的解析
Gson gson = new Gson(); //基本資料類型的解析 int i = gson.fromJson("100",int.class); double d = gson.fromJson("99.99",double.class);//99.99字元串 double ds = gson.fromJson("\"99.99\"",double.class);//“99.99”字元串 boolean b = gson.fromJson("true",boolean.class); String str = gson.fromJson("string",String.class); Log.e("LKing","int = "+i);//結果:100 Log.e("LKing","double = "+d);//結果:99.99 Log.e("LKing","doubles = "+ds);//結果:99.99 Log.e("LKing","boolean = "+b);//結果:true Log.e("LKing","string = "+str);//結果:string 注:double:不論99.99還是“99.99”,都會解析成double類型的99.99 |
2. 基本資料類型的生成
String jsonInt = gson.toJson(100); String jsonDouble = gson.toJson(99.99); String jsonBoolean = gson.toJson(true); String jsonString = gson.toJson("string"); Log.e("LKing","jsonInt = "+jsonInt);//結果:100 Log.e("LKing","jsonDouble = "+jsonDouble);//結果:99.99 Log.e("LKing","jsonBoolean = "+jsonBoolean);//結果:true Log.e("LKing","jsonString = "+jsonString);//結果:string |
3. POJO類的生成與解析
POJO類:成員變量名就是Json的key值 public class TestPerson { private String name; private int age; public TestPerson(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } } |
生成JSON
//POJO資料類型的生成 TestPerson testPerson = new TestPerson("張三",20); String jsonObject = gson.toJson(testPerson); Log.e("LKing","jsonObject = "+jsonObject); //結果:{"age":20,"name":"張三"} |
解析JSON
//POJO資料類型的解析 TestPerson test = gson.fromJson(jsonObject,TestPerson.class); String name = test.getName(); int age = test.getAge(); Log.e("LKing","name = "+name);//結果:張三 Log.e("LKing","age = "+age);//結果:20 |
4. 屬性重命名@SerializedName
Json資料命名習慣不同 1)期望Json {"name":"張三","age":20,"emailAddress":"[email protected]"} 2)實際Json {"name":"張三","age":20,"email_address":"[email protected]"} 如何相容兩種不同的命名習慣?在POJO類中 @SerializedName("email_address") public String emailAddress; Json資料命名習慣不同,多種key命名 1)期望Json {"name":"張三","age":20,"emailAddress":"[email protected]"} 2)實際第一種Json {"name":"張三","age":20,"email_address":"[email protected]"} 3)實際第二種Json {"name":"張三","age":20,"email":"[email protected]"} 如何相容上面多種key命名:alternate接收一個String數組 @SerializedName(value = "email_address",alternate = {"email_address","email"}) public String emailAddress; 當上面的key(emailAddress、email_address、email)出現任何一個時都可以擷取其對應的value值,當多種情況同時出現,以最後一個出現的值為準,如下 {"name":"張三","age":20,"emailAddress":"[email protected]","email_address":"[email protected]","email":"[email protected]"} 擷取的結果:emailAddress = [email protected]; |
5. 數組兩種解析方式
1)使用數組解析
Gson gson = new Gson(); String jsonArray = "[\"Android\",\"Java\",\"PHP\"]"; String[] strings = gson.fromJson(jsonArray, String[].class); for (int i=0;i<3;i++){ Log.e("LKing","str = "+strings[i]);//結果:Android、Java、PHP } |
JSON字元串數組,使用List解析,直接将String[].class改為List<String>.class是不行的。對于Java來說List<String>和List<TestPerson>這兩個位元組碼檔案都是List.class,這是Java泛型使用時要注意的“泛型擦除”。
當我們希望将Json字元串數組使用List<String>解析(List對于增删都是比較友善)
2)使用List解析
Gson gson = new Gson(); String jsonArray = "[\"Android\",\"Java\",\"PHP\"]"; List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType()); Log.e("LKing","str = "+stringList.toString());//結果:[Android,Java,PHP] |
注:TypeToken的構造方法是protected修飾的,是以上面才會寫成
new TypeToken<List<String>>(){}.getType
而不是new TypeToken<List<String>>().getType