如何用Kotlin Serialization序列化/反序列化未引号JSON字段?
用Kotlin Serialization处理未加引号的JSON字段(存储为字符串)
完全可以通过自定义序列化器实现这个需求。默认的Kotlin Serialization字符串序列化器仅处理带引号的JSON字符串,而你的场景中geometryJson字段在JSON里是原生JSON结构(如数组、对象),需要自定义逻辑完成「原生JSON结构 ↔ String」的双向转换。
实现步骤
1. 定义自定义序列化器
创建一个实现KSerializer<String>的序列化器,重写序列化和反序列化逻辑:
import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement object GeometryJsonSerializer : KSerializer<String> { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("GeometryJson", PrimitiveKind.STRING) // 反序列化:将JSON中的原生结构转为String override fun deserialize(decoder: Decoder): String { val jsonElement = decoder.decodeJsonElement() return jsonElement.toString() } // 序列化:将String转为原生JSON结构写入 override fun serialize(encoder: Encoder, value: String) { val jsonElement = Json.parseToJsonElement(value) encoder.encodeJsonElement(jsonElement) } }
2. 标记目标字段使用自定义序列化器
在GeometryItem的geometryJson字段上添加注解,指定使用上面的自定义序列化器:
import kotlinx.serialization.Serializable enum class GeometryType { Point, LineString, Polygon } @Serializable data class GeometryItem( val type: GeometryType, @Serializable(with = GeometryJsonSerializer::class) val geometryJson: String )
注意:你的原代码中字段名拼写为
geomtryJson,但示例JSON里是geometryJson,必须保持两者一致,否则反序列化会失败。
3. 测试序列化与反序列化
import kotlinx.serialization.json.Json fun main() { // 示例JSON(geometryJson为无引号的数组) val jsonString = """ { "type": "Point", "geometryJson": [12.0, 11.0] } """.trimIndent() // 反序列化:将JSON转为GeometryItem对象 val item = Json.decodeFromString<GeometryItem>(jsonString) println(item.geometryJson) // 输出: [12.0, 11.0] // 序列化:将对象转回JSON val serializedJson = Json.encodeToString(item) println(serializedJson) // 输出: {"type":"Point","geometryJson":[12.0,11.0]} }
注意事项
- 确保
geometryJson对应的字符串是有效的JSON格式,否则序列化时Json.parseToJsonElement会抛出解析异常。 - 该序列化器支持任意复杂的JSON结构(嵌套对象、混合数组等),因为
JsonElement可以表示所有JSON类型。
内容的提问来源于stack exchange,提问作者Semyon Tikhonenko
相关产品推荐
相关产品推荐

