You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何对Kotlin的JsonObject进行格式化(Pretty Print)输出?

如何对Kotlin的JsonObject进行格式化(Pretty Print)输出?

嗨,我来帮你搞定这个格式化输出的问题!你之前踩的坑我也遇过——Kotlin Serialization里的JsonObject不是普通的可序列化数据类,直接用encodeToString(myJson)肯定会报错,因为它得要显式指定序列化策略才行。不过别担心,两个简单办法就能实现漂亮的格式化输出:

方法一:显式指定JsonElement序列化器

这是最直接的修复方式,因为JsonObject继承自JsonElement,我们只要把JsonElement.serializer()作为第一个参数传给encodeToString,就能让格式化工具正确识别它:

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put

fun main() {
    // 先创建你的JsonObject
    val myJson = buildJsonObject {
        put("a", "b")
        put("c", "d")
        // 加个嵌套对象测试效果
        put("nested", buildJsonObject {
            put("x", 1)
            put("y", 2)
        })
    }

    // 配置格式化规则
    val prettyJsonConfig = Json {
        prettyPrint = true
        prettyPrintIndent = "  " // 这里可以自定义缩进,比如换成"\t"用制表符
    }

    // 关键一步:传入JsonElement.serializer()处理JsonObject
    val prettyOutput = prettyJsonConfig.encodeToString(JsonElement.serializer(), myJson)
    println(prettyOutput)
}

运行后你就能看到排版整齐的JSON了,比如:

{
  "a": "b",
  "c": "d",
  "nested": {
    "x": 1,
    "y": 2
  }
}

方法二:封装成扩展函数(推荐)

如果你的项目里经常要格式化JsonObject,不如把逻辑封装成扩展函数,用起来超顺手:

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject

// 给JsonObject加一个扩展函数
fun JsonObject.prettyPrint(indent: String = "  "): String {
    return Json {
        prettyPrint = true
        prettyPrintIndent = indent
    }.encodeToString(JsonElement.serializer(), this)
}

// 调用的时候特别简单
fun main() {
    val myJson = buildJsonObject {
        put("a", "b")
        put("c", "d")
    }
    println(myJson.prettyPrint()) // 默认用两个空格缩进
    // 也可以指定制表符缩进:println(myJson.prettyPrint("\t"))
}

为什么原来的代码会报错?

简单说下原因:你之前写的prettyJson.encodeToString(myJson),这个方法的默认重载只适用于用@Serializable注解标记的类——这类类Kotlin Serialization能自动生成序列化策略。但JsonObject是构建JSON树的底层节点类型,没有自带的默认序列化策略,所以必须显式告诉工具要用JsonElement.serializer()来处理它。

备注:内容来源于stack exchange,提问作者Gabriel Furstenheim

火山引擎 最新活动