鲁迅认识的那只猹

使用Gson解析Json
使用Gson解析JsonOverview在日常的开发中,我们经常得需要解析Json数据,烦不胜烦,还好有 Gson...
扫描右侧二维码阅读全文
30
2018/08

使用Gson解析Json

使用Gson解析Json

Overview

在日常的开发中,我们经常得需要解析Json数据,烦不胜烦,还好有 Gson 这一开源类库来帮助我们处理这些繁琐的工作。大体上Json的数据格式大概可以分为以下几种:

  • Json数据是一个对象
  • Json数据是一个对象数组
  • Json数据是一个对象,但是对象中嵌套着其他的对象或者数组

PS: 本文代码通过Kotlin语言描述

解析简单对象

这是一个Student类的Json数据,接下来我们要通过Gson解析它。

{
    "s_num":"s00001",
    "age":18,
    "gender":"M",
    "name":"LD"
}

要想使用Gson解释Json数据,首先得有已有与Json数据相对应的实体类。

data class Student(@SerializedName("s_num")
                   val studentNumber: String,
                   val name: String,
                   val age: Int,
                   val gender: Char) {
    override fun toString(): String {
        return "Student(studentNumber='$studentNumber', name='$name', age=$age, gender=$gender)"
    }
}

上面的类就是我们为了解释Json而建立的实体类了,请注意,我们在实体类中使用了一个 @SerializedName 注解,这个注解的作用解释,给我们的属性添加一个重命名。 因为在上面的Json数据中 s_num 这个字段名,是不太符合我们的编程规范的。但是我们又得解析它,所以通过这个注解来解决命名的问题。

下面是解析代码:

private fun analystJson(json: String) {
    val student = Gson().fromJson<Student>(json, Student::class.java)
    student.toString().e()
}
//输出结果
****************************************************************
* Student(studentNumber='s00001', name='LD', age=18, gender=M) *
****************************************************************

解析Json数组

[
    {
        "age":18,
        "gender":"M",
        "name":"LD",
        "s_num":"s00001"
    },
    {
        "age":19,
        "gender":"M",
        "name":"LD2",
        "s_num":"s00002"
    },
    {
        "age":20,
        "gender":"M",
        "name":"LD3",
        "s_num":"s00003"
    }
]

解析代码如下

private fun analystJsonArray(json: String) {
    val gson = Gson()
    val jsonParser = JsonParser()
    val jsonElement = jsonParser.parse(json)
    val jsonArray = jsonElement.asJsonArray

    val studentList = mutableListOf<Student>()

    jsonArray.forEach {
        studentList.add(gson.fromJson<Student>(it, Student::class.java))
    }

    "Student Count=${studentList.size}".i()
}

//输出结果
*******************
* Student Count=3 *
*******************

简化代码

写到这里,解析Json还是非常麻烦啊,我们得把这些代码封装一下,支持泛型才能解放我们的双手。

//将解析Json对象的方法封装一下
private fun <T> analystJson(json: String, cls: Class<T>): T {
    return Gson().fromJson<T>(json, cls)
}

//调用封装的方法
val obj: Student = analystJson(json, Student::class.java)
obj.toString().e()

//输出结果
****************************************************************
* Student(studentNumber='s00001', name='LD', age=18, gender=M) *
****************************************************************

上面我们已将将Gson解析对象的方法封装了一下,现在这个方法可以支持任意类型的对象的转化了,但是上面还是有些繁琐啊,我们又传递了个 Class 对象进去作为参数来帮助我们解析Json,多传递了这个一个参数,我们的方法就显得很笨拙了,那么我们能不能想办法不传递Class对象呢? 当然的可以的了。

private inline fun <reified T> analystJson(json: String): T {
    return Gson().fromJson<T>(json, T::class.java)
}

这里采用了一些Kotlin的特性 inline(内联函数)reified(类型具体化) 关于这两点这里就不在多说,有兴趣的可以自行查阅一下资料。

总结

实际上不管是,解析单个的Json对象,还是解析Json数组或者是更复杂的嵌套对象,使用上面的简化方法就都可以解决了。

Last modification:August 30th, 2018 at 10:36 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment