Detailed explanation of Android Gson usage

Json is a textual data interchange format that is more lightweight than xml. There are many ways to parse and generate Json. The most commonly used class libraries on the Android platform are Gson and FastJson. Here is Gson.

Gson's GitHub home page is here: Gson

1. Basic usage of Gson

1.1. Gson object

Before serializing and deserializing, you need to instantiate an  com .google.gson.Gson object. There are two ways to obtain a Gson object.

        //通过构造函数来获取
        Gson gson = new Gson();
        //通过 GsonBuilder 来获取,可以进行多项特殊配置
        Gson gson = new GsonBuilder().create();
  • 1
  • 2
  • 3
  • 4

1.2. Generate Json

Using Gson can easily generate Json strings by using  addProperty four overloaded methods

    public static void main(String[] args) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("String", "leavesC");
        jsonObject.addProperty("Number_Integer", 23);
        jsonObject.addProperty("Number_Double", 22.9);
        jsonObject.addProperty("Boolean", true);
        jsonObject.addProperty("Char", 'c');
        System.out.println();
        System.out.println(jsonObject);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

addProperty The bottom layer of the method calls the  add(String property, JsonElement value) method, that is, the basic data type is converted into  a JsonElement  object. JsonElement is an abstract class, and  JsonObject  inherits JsonElement, so we can build a JsonElement through JsonObject itself.

    public static void main(String[] args) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("String", "leavesC");
        jsonObject.addProperty("Number", 23);
        jsonObject.addProperty("Number", 22.9);
        jsonObject.addProperty("Boolean", true);
        jsonObject.addProperty("Char", 'c');

        JsonObject jsonElement = new JsonObject();
        jsonElement.addProperty("Boolean", false);
        jsonElement.addProperty("Double", 25.9);
        jsonElement.addProperty("Char", 'c');
        jsonObject.add("JsonElement", jsonElement);

        System.out.println();
        System.out.println(jsonObject);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

1.3, Json and array, List conversion

Json array vs String array

    public static void main(String[] args) {
        //Json数组 转为 字符串数组
        Gson gson = new Gson();
        String jsonArray = "[\"https://github.com/leavesC\",\"https://www.jianshu.com/u/9df45b87cfdf\",\"Java\",\"Kotlin\",\"Git\",\"GitHub\"]";
        String[] strings = gson.fromJson(jsonArray, String[].class);
        System.out.println("Json数组 转为 字符串数组: ");
        for (String string : strings) {
            System.out.println(string);
        }
        //字符串数组 转为 Json数组
        jsonArray = gson.toJson(jsonArray, new TypeToken<String>() {
        }.getType());
        System.out.println("\n字符串数组 转为 Json数组: ");
        System.out.println(jsonArray);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Json array vs List

    public static void main(String[] args) {
        //Json数组 转为 List
        Gson gson = new Gson();
        String jsonArray = "[\"https://github.com/leavesC\",\"https://www.jianshu.com/u/9df45b87cfdf\",\"Java\",\"Kotlin\",\"Git\",\"GitHub\"]";
        List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {
        }.getType());
        System.out.println("\nJson数组 转为 List: ");
        for (String string : stringList) {
            System.out.println(string);
        }
        //List 转为 Json数组
        jsonArray = gson.toJson(stringList, new TypeToken<List<String>>() {
        }.getType());
        System.out.println("\nList 转为 Json数组: ");
        System.out.println(jsonArray);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

1.4, serialization and deserialization

Gson also provides  two methods for converting Model toJson() and  fromJson() Json. The former implements serialization and the latter implements deserialization. 
First, declare a User class

/**
 * 作者:chenZY
 * 时间:2018/3/17 18:32
 * 描述:https://github.com/leavesC
 */
public class User {

    private String name;

    private int age;

    private boolean sex;

    public User(String name, int age, boolean sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                '}';
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

The serialization method is very simple, call the toJson method of the gson object, and pass in the object to be serialized

    public static void main(String[] args) {
        //序列化
        User user = new User("leavesC", 24, true);
        Gson gson = new Gson();
        System.out.println();
        System.out.println(gson.toJson(user));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Deserialization is also similar

    public static void main(String[] args) {
        //反序列化
        String userJson = "{\"name\":\"leavesC\",\"age\":24,\"sex\":true}";
        Gson gson = new Gson();
        User user = gson.fromJson(userJson, User.class);
        System.out.println();
        System.out.println(user);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Second, attribute renaming

Continue to use the User class declared in the previous section. According to the attribute names declared by the User class, the mobile terminal developers hope that the data format returned by the interface is as follows

{"name":"leavesC","age":24,"sex":true}
  • 1

如果没有和服务器端沟通好或者是 API 改版了,接口返回的数据格式可能是这样的

{"Name":"leavesC","age":24,"sex":true}
  • 1
{"userName":"leavesC","age":24,"sex":true}
  • 1

如果继续使用上一节介绍的方法,那无疑会解析出错 
例如

    public static void main(String[] args) {
        //反序列化
        String userJson = "{\"userName\":\"leavesC\",\"age\":24,\"sex\":true}";
        Gson gson = new Gson();
        User user = gson.fromJson(userJson, User.class);
        System.out.println();
        System.out.println(user);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

name 属性值解析不到,所以为 null 

此时为了兼顾多种格式的数据,就需要使用 SerializedName 注解 
根据 SerializedName 的声明来看,SerializedName 包含两个属性值,一个是字符串,一个是字符串数组,而字符串数组含有默认值

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface SerializedName {
    String value();

    String[] alternate() default {};
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

SerializedName 的作用是为了在序列化或反序列化时,指导 Gson 如果将原有的属性名和其它特殊情况下的属性名联系起来

例如,修改 User 类,为 name 声明 SerializedName 注解,注解值为 userName

/**
 * 作者:chenZY
 * 时间:2018/3/17 18:32
 * 描述:https://github.com/leavesC
 */
public class User {

    @SerializedName("userName")
    private String name;

    private int age;

    private boolean sex;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在序列时,Json 格式就会相应改变

    public static void main(String[] args) {
        //序列化
        User user = new User("leavesC", 24, true);
        Gson gson = new Gson();
        System.out.println();
        System.out.println(gson.toJson(user));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在反序列化时也一样,能够解析到正确的属性值

    public static void main(String[] args) {
        //反序列化
        String userJson = "{\"userName\":\"leavesC\",\"age\":24,\"sex\":true}";
        Gson gson = new Gson();
        User user = gson.fromJson(userJson, User.class);
        System.out.println();
        System.out.println(user);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

还有个问题没解决,为了应对多种属性名不一致的情况,难道我们要声明多个 User 类吗?这显然是不现实的,所以还需要为 User 类设置多个备选属性名,这就需要用到 SerializedName 注解的另一个属性值 alternate 了。

/**
 * 作者:chenZY
 * 时间:2018/3/17 18:32
 * 描述:https://github.com/leavesC
 */
public class User {

    @SerializedName(value = "userName", alternate = {"user_name", "Name"})
    private String name;

    private int age;

    private boolean sex;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

以下几种情况都能够被正确的反序列化

    public static void main(String[] args) {
        //反序列化
        Gson gson = new Gson();
        String userJson = "{\"userName\":\"leavesC\",\"age\":24,\"sex\":true}";
        User user = gson.fromJson(userJson, User.class);
        System.out.println();
        System.out.println(user);

        userJson = "{\"user_name\":\"leavesC\",\"age\":24,\"sex\":true}";
        user = gson.fromJson(userJson, User.class);
        System.out.println();
        System.out.println(user);

        userJson = "{\"Name\":\"leavesC\",\"age\":24,\"sex\":true}";
        user = gson.fromJson(userJson, User.class);
        System.out.println();
        System.out.println(user);
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325727020&siteId=291194637