Gson的使用筆記

SerializedName註解

使用Gson解析json成對象時默認的是將json裏對應字段的值解析到java對象裏對應字段的屬性裏面;但是開發中我們經常會遇到我們自己定義的java對象裏的屬性名跟json裏的字段名是不一樣的,這種情況怎麼辦呢,這時我們就可以使用@SerializedName註解來將對象裏的屬性跟json裏字段對應值匹配起來。
比如:
返回的json格式如下:

{
	"package": 0
}

我自己接受的類的屬性定義如下:

public class User {
	int id;
}

因爲package和java的關鍵字衝突,java中無法定義package字段;
這個時候爲了成功解析json,再User屬性上加上 @SerializedName註解;

public class User {
	@SerializedName("package")
	int id;
}

加上@SerializedName(“package”) 之後,這個User類就可以成功接受上面的json了;
如果還有其他字段也想要User來接受怎麼辦?

{
	"am": 0
}
或
{
	"test": 0
}

這個時候還想使用User類接受的話使用alternate接受一個String數組

public class User {
	@SerializedName(value = "package", alternate = {"am", "test"})
	int id;
}
transient關鍵字會避免被序列化

比如下面 private transient int value3 = 3;
BagOfPrimitives 類中的屬性字段value3使用transient關鍵字就會避免被序列化,
這個類生成的對象中的values3字段不會被轉到json裏去;

public class BagOfPrimitives {
  private int value1 = 1;
  private String value2 = "abc";
  private transient int value3 = 3; // 使用transient關鍵字會避免被序列化
}

// Gson解析
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);  
// ==> json is {"value1":1,"value2":"abc"}

{“value1”:1,“value2”:“abc”} 這串json中不會包含values字段

TypeToken處理泛型的解析

比如如下的json:
String json = “{“code”:1,“message”:“success”}”;
可以這樣來解析

public class BaseModel {
    public int code;
    public String message;
}
Gson gson = new Gson();
BaseModel model= gson.fromJson(json,BaseModel.class);

使用上面的方法就可以解析了,但是實際開發中,我們不是這樣的,我們需要泛型類定義,比如返回如下結構:

{
    "code":200,
    "message":"success",
    "data":"{...}"
}

其中data對應的結構不定, 一種考慮是使用泛型:
定義如下:

public class BaseModel<T> {
    public int code;
    public String message;
    public T data;
}

T可以是任意的結構類型:
這個時候需要考慮這個泛型T,怎麼去解析,gson中就要使用TypeToken來處理

    public static <T> BaseModel<T> parse(String json, Class<T> cls) {
        Gson gson = new Gson();
        BaseModel<T> model = gson.fromJson(json, new TypeToken<BaseModel<T>>() {
        }.getType());
        return model;
    }
Gson的適配器TyepAdapter,JsonSerializer與JsonDeserializer

使用的User類

public class User {
    public int age;
    public String name;
}

使用的事例:

User user = new User("怪盜kidou", 24);
Gson gson = new GsonBuilder()
        //爲User註冊TypeAdapter
        .registerTypeAdapter(User.class, new UserTypeAdapter())
        .create();
System.out.println(gson.toJson(user));

使用的UserTypeAdapter

public class UserTypeAdapter extends TypeAdapter<User> {

    //User對象轉換成json
    @Override
    public void write(JsonWriter out, User user) throws IOException {
        out.beginObject();
        out.name("m").value(user.name);
        out.name("a").value(user.age);
        out.endObject();
	//在這個方法裏面,可以吧對象轉換成任意的json字符串
    }

    //json轉換成User對象
    @Override
    public User read(JsonReader in) throws IOException {
        User user = new User();
        in.beginObject();
        while (in.hasNext()) {
            switch (in.nextName()) {
                case "m":
                    user.name = in.nextString();
                    break;
                case "a":
                    user.age = in.nextInt();
                    break;
            }
        }
        in.endObject();
        return user;
    }
//在這個方法裏,可以吧json轉換成對象
}

JsonSerializer 和JsonDeserializer 不用像TypeAdapter一樣,必須要實現序列化和反序列化的過程,你可以據需要選擇,如只接管序列化的過程就用 JsonSerializer ,只接管反序列化的過程就用 JsonDeserializer
反序列化

		String json = "{\"age\":1,\"name\":\"success\"}";
        Gson gson = new GsonBuilder()
                //爲User註冊TypeAdapter
                .registerTypeAdapter(User.class, new JsonDeserializer<User>() {
                    @Override
                    public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                        //這個方法把json序列化成User對象
                        Log.e("1234", "-----------: \n" + json.toString());
                        Log.e("1234", "-----------:\n" + json.isJsonObject());
                        JsonObject object = json.getAsJsonObject();
                        object.has("age");
                        Log.e("1234", "-----------age: " + (object.has("age")));
                        Log.e("1234", "-----------name: " + (object.has("name")));
                        Log.e("1234", "--------------:" + (object.size()));
                        object.keySet().iterator();
                        for (String str : object.keySet()) {
                            Log.e("1234", "--------------keySet: " + str);
                        }
                        for (Iterator<Map.Entry<String, JsonElement>> iterator = object.entrySet().iterator(); iterator.hasNext(); ) {
                            Map.Entry<String, JsonElement> entry = iterator.next();
                            Log.e("1234", "---------------key: " + entry.getKey() + "------value: " + entry.getValue());
                        }
                        int age = object.getAsJsonPrimitive("age").getAsInt();
                        Log.e("1234", "----------------------age的值: " + age);
                        return new User(1, "11");
                    }
                })
                .create();
        Log.e("1234", "--------------:\n " + gson.fromJson(json, User.class));

序列化

        User u = new User(24, "火影忍者");
        Gson gson = new GsonBuilder()
                //爲User註冊TypeAdapter
                .registerTypeAdapter(User.class, new JsonSerializer<User>() {

                    @Override
                    public JsonElement serialize(User user, Type typeOfSrc, JsonSerializationContext context) {
                        JsonObject jsonObject = new JsonObject();
                        jsonObject.add("age_age", new JsonPrimitive(user.age));
                        jsonObject.add("name_name", new JsonPrimitive(user.name));
                        return jsonObject;
                    }
                })
                .create();
        Log.e("1234", "--------------:\n " + gson.toJson(u));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章