You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:01:18