基本使用
构建json对象代码为何如此繁琐?
比如构建如下json:
{
"cpu": 10,
"memory": {
"total": 2048,
"usage": 800
},
"loadingTime": 15
}
使用JsonObject构造函数
val jsonObject = JsonObject(
mapOf(
"cpu" to JsonPrimitive(10),
"memory" to JsonObject(
mapOf(
"total" to JsonPrimitive(2048),
"usage" to JsonPrimitive(800),
),
),
"loadingTime" to JsonPrimitive(15),
),
)
使用buildJsonObject:
val jsonObject = buildJsonObject {
put("cpu", JsonPrimitive(10))
put("memory",
buildJsonObject {
put("total", JsonPrimitive(2048))
put("usage", JsonPrimitive(800))
},
)
put("loadingTime", JsonPrimitive(15))
},
由于JsonObject严格限制了value的类型,导致我们的构建代码过于啰嗦。
再来欣赏下mapOf的版本:
val map = mapOf(
"cpu" to 10,
"memory" to mapOf(
"total" to 2048,
"usage" to 800,
),
"loadingTime" to 15,
)
明显mapOf更加简洁,几乎接近原始的json。
如何支持媲美mapOf的语法?
fun jsonOf(vararg pairs: Pair<String, Any?> = emptyArray()): JsonElement {
return mapOf(*pairs).toJsonElement()
}
private fun Any?.toJsonElement(): JsonElement = when (this) {
null -> JsonNull
is JsonElement -> this
is Number -> JsonPrimitive(this)
is Boolean -> JsonPrimitive(this)
is String -> JsonPrimitive(this)
is Array<*> -> JsonArray(map { it.toJsonElement() })
is List<*> -> JsonArray(map { it.toJsonElement() })
is Map<*, *> -> JsonObject(map { it.key.toString() to it.value.toJsonElement() }.toMap())
else -> Json.encodeToJsonElement(serializer(this::class.createType()), this)
}
构建上述json的代码如下:
val json = jsonOf(
"cpu" to 10,
"memory" to jsonOf(
"total" to 2048,
"usage" to 800,
),
"loadingTime" to 15,
)
其中this::class.createType()这里使用到了反射,需要引入implementation(kotlin("reflect"))
参考:kotlinlang.org/docs/reflec…
反序列化泛型支持
val data: T = Json.decodeFromJsonElement(serializer(T::class.createType()), json)
如果<T>不能声明为reified, 可以通过反射拿到对应的KType