Gson進階學習

在上一篇中,主要研究了其基本的用法,本篇將總結Gson的一些高級技能。

1、 @SerializedName 註解的使用

@SerializedName 註解是屬性重命名的方法,舉例說明:

Android一般使用駝峯式命名,但如果此時和我們進行數據交互的後臺是PHP工程師,那我們往往將會得到下劃線分割的方式進行命名的數據,比如:

Android開發希望的json數據是:

{"name":"小明","homeAddress":"中國xxxxxxxxxx","age":16,"sex":true}
但PHP習慣返回的數據是:

{"name":"小明","home_address":"中國xxxxxxxxxx","age":16,"sex":true}
這時就需要用到@SerializedName 註解,方法如下:

在實體類中通過如下代碼進行註解

@SerializedName("home_address")
public String homeAddress;
此時就可以通過反射正確的解析json數據。

若出現命名混亂,後臺又不願意改,比如:

{"name":"小明","home_address":"中國xxxxxxxxxx","age":16,"sex":true}
{"name":"小明","homeaddress":"中國xxxxxxxxxx","age":16,"sex":true}
{"name":"小明","home":"中國xxxxxxxxxx","age":16,"sex":true}


可以通過如下方式進行調整:

@SerializedName(value = "homeAddress", alternate = {"home", "home_address","homeaddress"})
public String homeAddress;
此時不管出現的是homeAdress、home、home_adress或者homeadress都可以正確的解析;


2、顯示Null的值

正常情況下:

User user=new User("小明",true,16,null);
String userJson = gson.toJson(user);
Log.i(TAG,userJson);//{"name":"小明","age":16,"sex":true}
若此時想要顯示

"homeAddress":null

需要進行如下配置:

Gson gson = new GsonBuilder()
        .serializeNulls()
        .create();
此時打印結果爲:

{"name":"小明","homeAddress":null,"age":16,"sex":true}


3、其他關於序列化的控制(不僅僅只包含列舉的,這些只是常用的)

<pre name="code" class="java">Gson gson = new GsonBuilder()
.disableInnerClassSerialization()
.setDateFormat("yyyy-MM-dd")//序列化和反序化時將時間以此形式輸出 
.disableHtmlEscaping()//html標籤不轉義 
 .create();







4、註解@Expose的使用

             簡單來說,@Expose控制對象中的參數是否需要序列化和反序列化,其中:

@Expose(deserialize = true,serialize = true) //序列化和反序列化都都生效
@Expose(deserialize = true,serialize = false) //反序列化時生效
@Expose(deserialize = false,serialize = true) //序列化時生效
@Expose(deserialize = false,serialize = false) // 和不寫一樣

通過代碼來解釋用法:

public class User {
@Expose(deserialize = false,serialize = true) 
private String name;//序列化時生效
private boolean sex; private int age;
@Expose(deserialize = false,serialize = false) 
private String homeAddress;// 和不寫一樣,不管是序列化還是反序列化都和正常使用一樣
}





此時,Gson必須通過如下的方式進行實例化:
Gson gson = new GsonBuilder()
        .excludeFieldsWithoutExposeAnnotation()
        .create();

5、@Since(int i)和@Until(int i)的用法

@Since(int i)和@Until(int i)是一種版本控制,當版本號大於Since的值時,會解析出該字段,否則不會解析出來,當版本號小於Until的時會解析出來該字段,否則不會。看代碼:

public class User {
    @Since(3)
    private String name;
    private boolean sex;
    private int age;
    @Until(5)
private String homeAddress;
}






解析代碼:

Gson gson = new GsonBuilder().setVersion(int version).create();
結果分析:

若version<3 則解析結果爲:{"homeAddress":“中國xxxxxxxx”,"age":16,"sex":true}

若version>=3並且version<5 則解析結果爲:{"name":"小明","homeAddress":“中國xxxxxxxx”,"age":16,"sex":true}

若version>=5 則解析結果爲:{"name":"小明","age":16,"sex":true}

其實範圍可以概括爲,Until之前Since之後;


6、通過訪問修飾符控制序列化和反序列化

訪問修飾符包括:public、private、protected、static 、final等,注意:static 會自動被排除。
通過代碼解釋:

<pre name="code" class="java">public class User {
    private String name;
    public boolean sex;
    static int age;
final String homeAddress;
}




Gson gson = new GsonBuilder()
        .excludeFieldsWithModifiers(Modifier.FINAL,Modifier.PRIVATE)
        .create();
System.out.println(gson.toJson(user));
// 結果:{"sex":true}

7、TypeAdapter的使用

TypeAdapter 是Gson的一個抽象類,用於接管某種類型的序列化和反序列化過程。

public abstract class TypeAdapter<T> {
    public abstract void write(JsonWriter out, T value) throws IOException;
    public abstract T read(JsonReader in) throws IOException;
}
使用示例基本類型:
Gson gson = new GsonBuilder()
        .registerTypeAdapter(Integer.class, new TypeAdapter<Integer>() {
            @Override
            public void write(JsonWriter out, Integer value) throws IOException {
                out.value(String.valueOf(value)); 
            }
            @Override
            public Integer read(JsonReader in) throws IOException {
                try {
                    return Integer.parseInt(in.nextString());
                } catch (NumberFormatException e) {
                    return -1;
                }
            }
        })
        .create();
使用示例自定義類型:

<pre name="code" class="java"><pre name="code" class="java">Gson gson = new GsonBuilder()
        .registerTypeAdapter(User.class, new UserTypeAdapter())
        .create();
UserTypeAdapter的定義:
public class UserTypeAdapter extends TypeAdapter<User> {

    @Override
    public void write(JsonWriter out, User value) throws IOException {
        out.beginObject();
        out.name("name").value(value.name);
        out.name("age").value(value.age);
        out.name("sex").value(value.sex);
out.name("homeAdress").value(value.homeAdress);
out.endObject(); 
} 
@Override
 public User read(JsonReader in) throws IOException {
 User user = new User(); 
in.beginObject(); 
while (in.hasNext()) { 
switch (in.nextName()) { 
case "name": user.name = in.nextString(); break; 
case "age": user.age = in.nextInt(); break;
 case "home": case "home_address": case "homeAddress": user.homeAddress = in.nextString(); break; 
} } 
in.endObject(); 
return user; }
}










8、JsonSerializer與JsonDeserializer的使用

如果你已經學會了TypeAdapter的使用,那麼你就已經回使用這兩個方法,他們唯一的區別在於TypeAdapter同時接管序列化和反序列化而JsonSerializer只接管序列化JsonDeserializer只接管反序列化。

9、@JsonAdapter註解的使用

該註解必須配合TypeAdpater,JsonSerializer或JsonDeserializer中的一個使用,其中是不需要

Gson gson = new GsonBuilder()

        .registerTypeAdapter(User.class, new UserTypeAdapter())

        .create();

直接Gson gson = new Gson();既可以將類似UserTypeAdapter的序列化和反序列化規則用於註解的類,使用示例:

@JsonAdapter(UserTypeAdapter.class)
public class User {
private String name;//序列化時生效
private boolean sex; private int age;
private String homeAddress;// 和不寫一樣,不管是序列化還是反序列化都和正常使用一樣
}





到此,就已經基本總結完了Gson幾乎全部用法,當然,肯定還有些遺漏,但常見的方法大概就這些了。


     





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章