Kotlin的Gson解析(反序列化)

2019.12更新

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

测试代码

data class Res<T>(
    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<Res<Result>>() {}.type
    val gson = Gson()
    val fromJson = gson.fromJson<Res<Result>>(str, resultType)

    print(fromJson.result)

    print(fromJson)
}

二次更新

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

Gson扩展方法

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

Gson扩展方法使用

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

val bean = Gson().fromJson<ResultBean>(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

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<MeiZiBean>
)

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.
 *
 * <p>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.</p>
 *
 * <p>Here is an example of how Gson is used for a simple Class:
 *
 * <pre>
 * 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
 * </pre></p>
 *
 * <p>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}:
 *
 * <pre>
 * Type listType = new TypeToken&lt;List&lt;String&gt;&gt;() {}.getType();
 * List&lt;String&gt; target = new LinkedList&lt;String&gt;();
 * target.add("blah");
 *
 * Gson gson = new Gson();
 * String json = gson.toJson(target, listType);
 * List&lt;String&gt; target2 = gson.fromJson(json, listType);
 * </pre></p>
 *
 * <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
 * for a more complete set of examples.</p>
 *
 * @see com.google.gson.reflect.TypeToken
 *
 * @author Inderjeet Singh
 * @author Joel Leitch
 * @author Jesse Wilson
 */
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容