Kotlin的Gson解析(反序列化)

2019.12更新

最新的Gson已经完全完全支持kotlin了,此篇文章已经变得索然无味了=。=

测试代码

data class Res(
    val error_code: Int,
    val reason: String,
    val result: T
)

data class Result(
    val h5url: String,
    val h5weixin: String
)

fun main() {
    println("start")
    val str = """
        {
    "reason": "请求成功",
    "result": {
        "h5url": "http://v.juhe.cn/wepiao/go?key=xxxxxxxxxxxxx",
        "h5weixin": "http://v.juhe.cn/wepiao/go?key=xxxxxxxxxx&s=weixin"
    },
    "error_code": 0
}
    """.trimIndent()
    val resultType = object : TypeToken>() {}.type
    val gson = Gson()
    val fromJson = gson.fromJson>(str, resultType)

    print(fromJson.result)

    print(fromJson)
}

二次更新

1.因为学了bennyhuo老师的新课程所以照着抄了个扩展方法,让Gson用起来更简单。
2.最近使用发现使用.java也可以解析了,不会为空了。不知道为什么,还需要研究。。。

Gson扩展方法

inline fun  Gson.fromJson(json: String) = fromJson(json, T::class.java)

Gson扩展方法使用

ResultBean为解析实体类,data为解析字符串

val bean = Gson().fromJson(data)

更新

Kotlin List和 MutableList 差异:可读写性

在使用JSON To Kotlin Class 插件,版本号v1.7.3时。
解析的集合为Kotlin的List,因为在Kotlin中,List为只读的,要想读写需要使用MutableList。
我在更新Adapter的时候发现的,明明数据有变化,显示却一直不变,原因就在这!!!


正文

同样的写法,在java中使用fastjson,gson到kotlin怎么就不灵了=。=!!!

Gson

序号 api 作用
1 toJson(Object) 序列化
2 fromJson(String, Class) 反序列化
3 JsonParser().parse(String) 解析字段

实体类生成工具

像Java中的GsonFormat,Kotlin中也有插件JsonToKotlinClass

Kotlin的Gson解析(反序列化)_第1张图片
JsonToKotlinClass

代码示例

1. 加入依赖

   //json解析
    api 'com.google.code.gson:gson:2.8.2'

2.创造数据

 val data = """{
  "error": false,
  "results": [
    {
      "_id": "5aa5cc6a421aa9103ed33c7c",
      "createdAt": "2018-03-12T08:40:10.360Z",
      "desc": "3-12",
      "publishedAt": "2018-03-12T08:44:50.326Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "https://ws1.sinaimg.cn/large/610dc034ly1fp9qm6nv50j20u00miacg.jpg",
      "used": true,
      "who": "daimajia"
    },
    {
      "_id": "5a8e0c41421aa9133298a259",
      "createdAt": "2018-02-22T08:18:09.547Z",
      "desc": "2-22",
      "publishedAt": "2018-02-22T08:24:35.209Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "https://ws1.sinaimg.cn/large/610dc034ly1foowtrkpvkj20sg0izdkx.jpg",
      "used": true,
      "who": "\u4ee3\u7801\u5bb6"
    },
    {
      "_id": "5a7b93d2421aa90d2cd3d7f8",
      "createdAt": "2018-02-08T08:03:30.905Z",
      "desc": "2-8",
      "publishedAt": "2018-02-08T08:13:24.479Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180208080314_FhzuAJ_Screenshot.jpeg",
      "used": true,
      "who": "daimajia"
    },
    {
      "_id": "5a6e5f88421aa9115696004f",
      "createdAt": "2018-01-29T07:40:56.269Z",
      "desc": "1-29",
      "publishedAt": "2018-01-29T07:53:57.676Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180129074038_O3ydq4_Screenshot.jpeg",
      "used": true,
      "who": "daimajia"
    },
    {
      "_id": "5a65381a421aa91156960022",
      "createdAt": "2018-01-22T09:02:18.715Z",
      "desc": "1-22",
      "publishedAt": "2018-01-23T08:46:45.132Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180122090204_A4hNiG_Screenshot.jpeg",
      "used": true,
      "who": "daimajia"
    },
    {
      "_id": "5a5bfc29421aa9115489927b",
      "createdAt": "2018-01-15T08:56:09.429Z",
      "desc": "1-15",
      "publishedAt": "2018-01-16T08:40:08.101Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180115085556_8AeReR_taeyeon_ss_15_1_2018_7_58_51_833.jpeg",
      "used": true,
      "who": "daimajia"
    },
    {
      "_id": "5a5411fb421aa90fef2035f3",
      "createdAt": "2018-01-09T08:51:07.91Z",
      "desc": "1-9",
      "publishedAt": "2018-01-10T07:57:19.486Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180109085038_4A7atU_rakukoo_9_1_2018_8_50_25_276.jpeg",
      "used": true,
      "who": "daimajia"
    },
    {
      "_id": "5a443fcb421aa90fe72536ed",
      "createdAt": "2017-12-28T08:50:19.747Z",
      "desc": "12-28",
      "publishedAt": "2018-01-04T13:45:57.211Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20171228085004_5yEHju_Screenshot.jpeg",
      "used": true,
      "who": "\u4ee3\u7801\u5bb6"
    },
    {
      "_id": "5a4ad432421aa90fe2f02d1a",
      "createdAt": "2018-01-02T08:37:06.235Z",
      "desc": "1-2",
      "publishedAt": "2018-01-02T08:43:32.216Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180102083655_3t4ytm_Screenshot.jpeg",
      "used": true,
      "who": "daimajia"
    },
    {
      "_id": "5a431acd421aa90fe50c02a8",
      "createdAt": "2017-12-27T12:00:13.664Z",
      "desc": "12-27",
      "publishedAt": "2017-12-27T12:13:22.418Z",
      "source": "chrome",
      "type": "\u798f\u5229",
      "url": "http://7xi8d6.com1.z0.glb.clouddn.com/20171227115959_lmlLZ3_Screenshot.jpeg",
      "used": true,
      "who": "daimajia"
    }
  ]
}"""

3.创建实体类(使用JsonToKotlinClass工具)

data class ResultBean(
        val error: Boolean,
        val results: List
)

data class MeiZiBean(
        val _id: String,
        val createdAt: String,
        val desc: String,
        val publishedAt: String,
        val source: String,
        val type: String,
        val url: String,
        val used: Boolean,
        val who: String
)

4.解析

        //注意必须是javaObjectType,要不会被擦除泛型
        val bean = Gson().fromJson(data, ResultBean::class.javaObjectType)
        val results = bean.results
        //验证是否有数据
        val s = results.toString()
        Log.e("main",s)

遇到的坑

之前一直写的是ResultBean::class.java,导致被泛型擦除,只能先解析成字符串,然后专门用TypeToken解析List,非常麻烦,网上看了很多文章也没有解决,最后还得自己发现。

示例代码


源码注释

/**
 * This is the main class for using Gson. Gson is typically used by first constructing a
 * Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)}
 * methods on it. Gson instances are Thread-safe so you can reuse them freely across multiple
 * threads.
 *
 * 

You can create a Gson instance by invoking {@code new Gson()} if the default configuration * is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various * configuration options such as versioning support, pretty printing, custom * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.

* *

Here is an example of how Gson is used for a simple Class: * *

 * Gson gson = new Gson(); // Or use new GsonBuilder().create();
 * MyType target = new MyType();
 * String json = gson.toJson(target); // serializes target to Json
 * MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
 * 

* *

If the object that your are serializing/deserializing is a {@code ParameterizedType} * (i.e. contains at least one type parameter and may be an array) then you must use the * {@link #toJson(Object, Type)} or {@link #fromJson(String, Type)} method. Here is an * example for serializing and deserializing a {@code ParameterizedType}: * *

 * Type listType = new TypeToken<List<String>>() {}.getType();
 * List<String> target = new LinkedList<String>();
 * target.add("blah");
 *
 * Gson gson = new Gson();
 * String json = gson.toJson(target, listType);
 * List<String> target2 = gson.fromJson(json, listType);
 * 

* *

See the Gson User Guide * for a more complete set of examples.

* * @see com.google.gson.reflect.TypeToken * * @author Inderjeet Singh * @author Joel Leitch * @author Jesse Wilson */

你可能感兴趣的:(Kotlin的Gson解析(反序列化))