Kotlinx.serialization VS Gson
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解析库有Moshi
、Jackson
、Gson
等,因为Java和Kotlin互相兼容,所以这些库也可以用在Kotlin,虽然可能会有一些小坑。
我们基于Kotlin的data class
定义一个User
的Bean,age
和role
字段分被设置默认值以是之类型非空
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相关推荐
- Gson替代方案Moshi使用教程
原文链接:新一代Json解析库Moshi使用及原理解析 推荐理由 硬伤:Gson无法解析设置Kotlin默认参数 全新JsonAdapter 解析效率高 报空异常(即是优点也是缺点) 概述 Moshi ...
- 更易于使用的Retrofit(不用写注解)
前言 声明的时候比Retrofit更加简单,而且因为是从Retrofit上改的,所以Retrofit能用的东西这个库也能用 修改的地方 1.如果参数不加任何注解,则默认是@Field,并且value为 ...
- 新一代Json解析库Moshi使用及原理解析
概述 Moshi是Square公司在2015年6月开源的有关Json的反序列化及序列化的框架,说到Json,大家应该很快想到Gson,FastJson以及Jackson等著名的开源框架,那为什么还需要 ...
- 尚硅谷雷神SpringBoot2超详细笔记和源码以及自己Bug修改和个人的体会
## 01.基础入门-SpringBoot2课程介绍 Spring Boot 2核心技术 Spring Boot 2响应式编程 学习要求 -熟悉Spring基础 -熟悉Maven使用 环境要求 Jav ...
- Kotlin Jetpack 实战:01. Kotlin 基础
背景 近几年,Android 相关的新技术层出不穷.往往这个技术还没学完,下一个新技术又出来了.很多人都是一脸黑人问号?不少开发者甚至开始哀嚎:"求求你们别再创造新技术了,我们学不动了!&q ...
- Kotlin Jetpack 实战: Kotlin 基础 | 开发者说·DTalk
本文原作者: 朱涛,原文发布于: 朱涛的自习室 https://mp.weixin.qq.com/s/MSbSPeWNlM5PJCFmLg2SVQ 背景 近几年,Android 相关的新技术层出不穷. ...
- Kotlin 越来越牛逼了!学Java都我想转了!
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 在过 ...
- springboot的自动配置原理
SpringBoot中的默认配置 通过刚才的学习,我们知道@EnableAutoConfiguration会开启SpringBoot的自动配置,并且根据你引入的依赖来生效对应的默认配置.那么问题来了: ...
- spring boot application.properties 属性详解
2019年3月21日17:09:59 英文原版: https://docs.spring.io/spring-boot/docs/current/reference/html/common-appli ...
- SpringBoot 2.1.5(20)---JSON
简介 Spring Boot 支持的 Json 库 Spring Web 中的序列化.反序列化 指定类的 Json 序列化.反序列化 @JsonTest Spring Boot 中的 json 配置 ...
最新文章
- 编写Makefile中遇到的各种奇葩问题汇总
- webstom新增vue模板
- UNIX环境高级编程 第12章 线程控制
- python excel合并_Python把多个Excel合并成一个Excel
- cmd运行python服务器,python如何利用paramiko执行服务器命令
- seaborn分布数据可视化:直方图|密度图|散点图
- [ffmpeg 扩展第三方库编译系列] 关于libopenjpeg mingw32编译问题
- 设计灵感|如果你喜欢多彩的配色搭配!看这里!
- jenkins html编辑,Jenkins HTML Publisher插件:Jenkins 1.643没有外部链接
- session跨域共享解决方案
- NYOJ 1272:表达式求值(2016河南省ACM-A)
- 盘点功能软件测试用例,盘点那些必不可少的“用例集”
- 2021爱分析・中国采购数字化趋势报告
- 基于Android的虚拟校园移动学习系统
- 【全志A64/R18】Android平台获取Chip ID
- 分享Java开发经验去鹅厂面试的经历,你值得~
- 修改RAC中的私网地址导致CRS启动失败
- apicloud mysql_apiCloud中的API对象
- 网易极客战记-KITHGARD地牢--健忘的宝石匠
- c语言中<< , >>的作用