天天看點

Android網絡資料解析之Gson

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