JSON is an open-standard file format or data interchange format that uses human-readable text to transmit data objects consisting of attribute-value pairs and array data types.

Java中常见的JSON解析库有MoshiJacksonGson等,因为Java和Kotlin互相兼容,所以这些库也可以用在Kotlin,虽然可能会有一些小坑。

我们基于Kotlin的data class定义一个User的Bean,agerole字段分被设置默认值以是之类型非空

data class User(val name: String,val email: String,val age: Int = 13,val role: Role = Role.Viewer
)enum class Role { Viewer, Editor, Owner }

接下来,我们将下列JSON对象解析成User

{"name" : "John Doe","email" : "john.doe@email.com"
}

先使用Gson写一个TestCase:

class JsonUnitTest {private val jsonString = """{"name" : "John Doe","email" : "john.doe@email.com"}""".trimIndent()@Testfun gsonTest() {val user = Gson().fromJson(jsonString, User::class.java)assertEquals("John Doe",user.name)assertEquals(null, user.role)assertEquals(0, user.age)
//      User(name=John Doe, email=john.doe@email.com, age=0, role=null)}}

上面的Test运行成功了。Gson在反序列化过程中,将基本型age设置了默认值0,将引用型role设置了null,这破坏了kotlin的非空类型编译期检查的限制,我们在调用user.role时可能出现crash。所以在Kotlin中进行反序列化时,我们希望能够遵循Kotlin的规范,识别这种非空类型。

Kotlinx.serialization

Kotlinx.serialization是Jetbrains针对Kotlin的推出序列化库。通过为KClass添加@Serializable注解,配合其配套的Kotlin Compiler Plugin,可以在编译期为在伴生对象中生成serializer()方法,serializer()方法返回一个KSerializer类型的序列化器。
KSerializer可以进行多种类型数据的序列化反序列化,例如 JSON、CBOR以及Protobuf

Kotlinx.serialization 还支持Kotlin MPP的跨平台使用,可以在JVM之外工作,例如用在Kotlin/Native或JavaScript中。

Kotlinx.serialization需要 Kotlin 1.3.30以上才可使用,如上所述,除了依赖runtime库以外, 还需要以来给一个Compiler Plugin用来进行字节码插桩。字节码插桩的一个直接好处就是可以实现零反射,性能更好。

我们基于Kotlinx.serialization测试一下上面的TestCase:

@Serializable
data class User(val name: String,val email: String,val age: Int = 13,val role: Role = Role.Viewer
)enum class Role { Viewer, Editor, Owner }class JsonUnitTest {private val jsonString = """{"name" : "John Doe","email" : "john.doe@email.com"}""".trimIndent()@Testfun gsonTest() {val user = Gson().fromJson(jsonString, User::class.java)assertEquals("John Doe", user.name)assertEquals(null, user.role)assertEquals(0, user.age)
//      User(name=John Doe, email=john.doe@email.com, age=0, role=null)}@Testfun jsonTest() {val user = Json.parse(User.serializer(), jsonString)assertEquals("John Doe", user.name)assertEquals(Role.Viewer, user.role)assertEquals(13, user.age)
//      User(name=John Doe, email=john.doe@email.com, age=13, role=Viewer)}
}

测试通过可以看见Kotlinx.serialization反序列化结果中的缺省值是data class中定义的值,更符合预期。

Kotlinx.serialization + Retrofit

我们都经常使用Retrofit+Gson的组合进行HTTP请求以及对请求结果进行反序列化。 如今我们也可以为Retrofit 添加 新的ConverterFactory,以适配Kotlinx.serialization的使用。

我肯可以定义自己的ConverterFactory,也可以使用第三方现成的,例如J神已将帮我们写好的一个https://github.com/JakeWharton/retrofit2-kotlinx-serialization-converter

val contentType = "application/json".toMediaType()val retrofit = Retrofit.Builder().baseUrl("https://www.example.com").addConverterFactory(Json(JsonConfiguration(strictMode = false)).asConverterFactory(contentType)).build()

可以通过JsonConfiguation进行配置,例如打开/关闭编码默认值,启用/禁用strictMode等。默认情况下strictMode处于启用状态,此时会检查JSON中是否存在unknown的key,并且不运行String像num类型的转换等。一个推荐做法是在debug模式下开启严格模式,在release包中关闭,可以提高线上的容错性。

最后

本文只是介绍了Kotlinx.serialization的基本用法,想了解更多内容可以参考官网以及 KotlinConf 2019: Design of Kotlin Serialization by Leonid Startsev

Kotlinx.serialization VS Gson相关推荐

  1. Gson替代方案Moshi使用教程

    原文链接:新一代Json解析库Moshi使用及原理解析 推荐理由 硬伤:Gson无法解析设置Kotlin默认参数 全新JsonAdapter 解析效率高 报空异常(即是优点也是缺点) 概述 Moshi ...

  2. 更易于使用的Retrofit(不用写注解)

    前言 声明的时候比Retrofit更加简单,而且因为是从Retrofit上改的,所以Retrofit能用的东西这个库也能用 修改的地方 1.如果参数不加任何注解,则默认是@Field,并且value为 ...

  3. 新一代Json解析库Moshi使用及原理解析

    概述 Moshi是Square公司在2015年6月开源的有关Json的反序列化及序列化的框架,说到Json,大家应该很快想到Gson,FastJson以及Jackson等著名的开源框架,那为什么还需要 ...

  4. 尚硅谷雷神SpringBoot2超详细笔记和源码以及自己Bug修改和个人的体会

    ## 01.基础入门-SpringBoot2课程介绍 Spring Boot 2核心技术 Spring Boot 2响应式编程 学习要求 -熟悉Spring基础 -熟悉Maven使用 环境要求 Jav ...

  5. Kotlin Jetpack 实战:01. Kotlin 基础

    背景 近几年,Android 相关的新技术层出不穷.往往这个技术还没学完,下一个新技术又出来了.很多人都是一脸黑人问号?不少开发者甚至开始哀嚎:"求求你们别再创造新技术了,我们学不动了!&q ...

  6. Kotlin Jetpack 实战: Kotlin 基础 | 开发者说·DTalk

    本文原作者: 朱涛,原文发布于: 朱涛的自习室 https://mp.weixin.qq.com/s/MSbSPeWNlM5PJCFmLg2SVQ 背景 近几年,Android 相关的新技术层出不穷. ...

  7. Kotlin 越来越牛逼了!学Java都我想转了!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 在过 ...

  8. springboot的自动配置原理

    SpringBoot中的默认配置 通过刚才的学习,我们知道@EnableAutoConfiguration会开启SpringBoot的自动配置,并且根据你引入的依赖来生效对应的默认配置.那么问题来了: ...

  9. spring boot application.properties 属性详解

    2019年3月21日17:09:59 英文原版: https://docs.spring.io/spring-boot/docs/current/reference/html/common-appli ...

  10. SpringBoot 2.1.5(20)---JSON

    简介 Spring Boot 支持的 Json 库 Spring Web 中的序列化.反序列化 指定类的 Json 序列化.反序列化 @JsonTest Spring Boot 中的 json 配置 ...

最新文章

  1. 编写Makefile中遇到的各种奇葩问题汇总
  2. webstom新增vue模板
  3. UNIX环境高级编程 第12章 线程控制
  4. python excel合并_Python把多个Excel合并成一个Excel
  5. cmd运行python服务器,python如何利用paramiko执行服务器命令
  6. seaborn分布数据可视化:直方图|密度图|散点图
  7. [ffmpeg 扩展第三方库编译系列] 关于libopenjpeg mingw32编译问题
  8. 设计灵感|如果你喜欢多彩的配色搭配!看这里!
  9. jenkins html编辑,Jenkins HTML Publisher插件:Jenkins 1.643没有外部链接
  10. session跨域共享解决方案
  11. NYOJ 1272:表达式求值(2016河南省ACM-A)
  12. 盘点功能软件测试用例,盘点那些必不可少的“用例集”
  13. 2021爱分析・中国采购数字化趋势报告
  14. 基于Android的虚拟校园移动学习系统
  15. 【全志A64/R18】Android平台获取Chip ID
  16. 分享Java开发经验去鹅厂面试的经历,你值得~
  17. 修改RAC中的私网地址导致CRS启动失败
  18. apicloud mysql_apiCloud中的API对象
  19. 网易极客战记-KITHGARD地牢--健忘的宝石匠
  20. c语言中<< , >>的作用

热门文章

  1. XFP与SFP+光模块的区别是什么?能相互连接吗?
  2. 列车停站方案_基于节点分级的高速铁路列车停站方案设计策略
  3. 【绝对原创】EFS加密文件真的可以解密!各位不要放弃哈~
  4. 什么是域名(Domain Name ) ?
  5. HGDB pg_stat_statements 用法
  6. 整理一道测试面试题(微信更换头像测试用例)
  7. c++的size_t
  8. 只用CSS实现轮播图
  9. 理解 Roslyn 中的红绿树(Red-Green Trees)
  10. 解决电脑右键菜单反应慢问题