首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Kotlin:将嵌套的JSON对象转换为文字字符串

Kotlin:将嵌套的JSON对象转换为文字字符串
EN

Stack Overflow用户
提问于 2020-10-22 16:39:26
回答 2查看 728关注 0票数 1

我有一个数据类,其属性的类型是另一个数据类,如下所示:

代码语言:javascript
运行
复制
@Serializable
data class Vehicle (
  val color: String,
  val miles: Int,
  val year: Int,
  val garage: Garage
)

@Serializable
data class Garage (
  val latitude: Float,
  val longitude: Float,
  val name: String
)

在序列化时,它会产生如下输出:

代码语言:javascript
运行
复制
{ 
  "color" : "black" , 
  "miles" : 35000 , 
  "year" : 2017 , 
  "garage" : { "latitude" : 43.478342 , "longitude" : -91.337000 , "name" : "Paul's Garage" }
}

但是,我希望garage是其JSON表示的文字字符串,而不是实际的JSON对象。换句话说,期望的输出是:

代码语言:javascript
运行
复制
{ 
  "color" : "black" , 
  "miles" : 35000 , 
  "year" : 2017 , 
  "garage" : "{ \"latitude\" : 43.478342 , \"longitude\" : -91.337000 , \"name\" : \"Paul's Garage\" }"
}

我如何在Kotlin中做到这一点?只用kotlinx.serialization就可以做到吗?或者Jackson/Gson绝对有必要吗?

请注意,此输出用于特定的用法。我不能覆盖基本序列化程序,因为我仍然需要从普通JSON序列化/反序列化(第一个示例)。换句话说,最好的方案是将第一个JSON样本转换为第二个样本,而不必让数据类直接生成第二个样本。

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-22 17:50:17

Vehicle创建自定义SerializationStrategy,如下所示:

代码语言:javascript
运行
复制
val vehicleStrategy = object : SerializationStrategy<Vehicle> {
    override val descriptor: SerialDescriptor
        get() = buildClassSerialDescriptor("Vehicle") {
            element<String>("color")
            element<Int>("miles")
            element<Int>("year")
            element<String>("garage")
        }

    override fun serialize(encoder: Encoder, value: Vehicle) {
        encoder.encodeStructure(descriptor) {
            encodeStringElement(descriptor, 0, value.color)
            encodeIntElement(descriptor, 1, value.miles)
            encodeIntElement(descriptor, 2, value.year)
            encodeStringElement(descriptor, 3, Json.encodeToString(value.garage))
        }
    }
}

然后将其传递给Json.encodeToString()

代码语言:javascript
运行
复制
val string = Json.encodeToString(vehicleStrategy, vehicle)

结果:

代码语言:javascript
运行
复制
{"color":"black","miles":35000,"year":2017,"garage":"{\"latitude\":43.47834,\"longitude\":-91.337,\"name\":\"Paul's Garage\"}"}

更多信息here

票数 1
EN

Stack Overflow用户

发布于 2021-09-01 05:02:47

下面是一个解决方案,其中包含一个用于Garage的自定义序列化程序和一个用于Vehicle的附加类。

GarageString序列化程序:

代码语言:javascript
运行
复制
object GarageToStringSerializer : KSerializer<Garage> {
    override val descriptor = PrimitiveSerialDescriptor("GarageToString", PrimitiveKind.STRING)
    override fun serialize(encoder: Encoder, value: Garage) = encoder.encodeString(Json.encodeToString(value))
    override fun deserialize(decoder: Decoder): Garage = Json.decodeFromString(decoder.decodeString())
}

辅助类:

代码语言:javascript
运行
复制
@Serializable
data class VehicleDto(
    val color: String,
    val miles: Int,
    val year: Int,
    @Serializable(GarageToStringSerializer::class)
    val garage: Garage
) {
    constructor(v: Vehicle) : this(v.color, v.miles, v.year, v.garage)
}

可以通过以下方式接收所需的结果:

代码语言:javascript
运行
复制
Json.encodeToString(VehicleDto(vehicle))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64478425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档