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

如何在Kotlin中使用Kotlinx Serialization编码未转义的原始JSON字符串

解决Kotlinx Serialization直接输出原始JSON字符串的问题

当使用Kotlinx Serialization作为网关服务的序列化工具时,若需要将后端返回的原始JSON字符串直接作为响应字段输出(而非转义成字符串),可以通过以下两种方案解决:

方案1:使用JsonElement替代String类型

这是最简洁直接的方案,JsonElement是Kotlinx Serialization中表示任意JSON节点的核心类型,序列化时会直接输出对应JSON结构,不会添加引号或转义字符。

修改后的完整代码:

import kotlinx.serialization.json.*
import kotlinx.serialization.Serializable

fun main() {
    // 从后端服务获取的原始JSON字符串
    val backingServiceResponse = """
        {"some":"json",id:123,content:[]}
    """.trimIndent()

    // 将字符串解析为JsonElement对象
    val contentJson = Json.parseToJsonElement(backingServiceResponse)

    // 创建客户端响应对象
    val packet = ExampleClientResponse("name", contentJson)

    val encodedPacket = Json.encodeToString(packet)

    println(encodedPacket)

    // 验证输出符合预期
    require("""{"name":"name","content":{"some":"json","id":123,"content":[]}}""".trimIndent() == encodedPacket)
}

@Serializable
data class ExampleClientResponse(
    val name: String,
    val content: JsonElement // 替换String为JsonElement类型
)

方案2:自定义序列化器(保留String字段类型)

如果因兼容性等原因必须保留content字段的String类型,可以自定义序列化器,跳过字符串的转义逻辑,直接输出原始JSON:

import kotlinx.serialization.*
import kotlinx.serialization.json.*

// 自定义序列化器:处理String类型的原始JSON输出
@Serializer(forClass = String::class)
object RawJsonStringSerializer : KSerializer<String> {
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("RawJsonString", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: String) {
        // 将字符串解析为JsonElement后直接写入编码器
        val jsonElement = Json.parseToJsonElement(value)
        (encoder as JsonEncoder).encodeJsonElement(jsonElement)
    }

    override fun deserialize(decoder: Decoder): String {
        // 反序列化时将JsonElement转回字符串
        val jsonElement = (decoder as JsonDecoder).decodeJsonElement()
        return Json.encodeToString(jsonElement)
    }
}

@Serializable
data class ExampleClientResponse(
    val name: String,
    @Serializable(with = RawJsonStringSerializer::class) // 应用自定义序列化器
    val content: String
)

fun main() {
    val backingServiceResponse = """
        {"some":"json",id:123,content:[]}
    """.trimIndent()

    val packet = ExampleClientResponse("name", backingServiceResponse)

    val encodedPacket = Json.encodeToString(packet)

    println(encodedPacket)

    require("""{"name":"name","content":{"some":"json","id":123,"content":[]}}""".trimIndent() == encodedPacket)
}

注意事项

  • 确保传入的字符串是合法JSON,否则解析过程会抛出异常
  • 你的Kotlin 1.8.0 + Kotlinx Serialization 1.4.1版本完全支持上述两种方案

内容的提问来源于stack exchange,提问作者aSemy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:12:12