Android开发中使用Gson的笔记

JSON简介

JSON 是一种文本形式的数据交换格式,它比XML更轻量、比二进制容易阅读和编写,调式也更加方便;解析和生成的方式很多,Java中最常用的类库有:JSON-Java、Gson、Jackson、FastJson等。

Gson的基本用法

Gson提供了fromJson() 和toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化;同时每个方法都提供了重载方法

基本数据类型的解析

Gson gson = new Gson();
int i = gson.fromJson("100", int.class); //100
double d = gson.fromJson("\"99.99\"", double.class);  //99.99
boolean b = gson.fromJson("true", boolean.class);     // true
String str = gson.fromJson("String", String.class);   // String

基本数据类型的生成

Gson gson = new Gson();
String jsonNumber = gson.toJson(100);       // 100
String jsonBoolean = gson.toJson(false);    // false
String jsonString = gson.toJson("String"); //"String"

类的生成与解析

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

生成JSON

Gson gson = new Gson();
User user = new User("张三",24);
String jsonObject = gson.toJson(user); // {"name":"张三","age":24}

解析JSON

Gson gson = new Gson();
String jsonString = "{\"name\":\"张三\",\"age\":24}";
User user = gson.fromJson(jsonString, User.class);

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; 

上面类中的属性字段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));

猜你喜欢

转载自blog.csdn.net/eyishion/article/details/92849766