简体   繁体   English

在 kotlinx.serialization 中编码/解码 JSON “字符串”

[英]Encode / decode JSON “string” in kotlinx.serialization

Is it possible to encode / decode any valid json objects in string format in a custom serializer.是否可以在自定义序列化程序中以字符串格式对任何有效的 json 对象进行编码/解码。 For example the code below but not let it serialize as json string but as any valid JSON with unknown structure?例如下面的代码,但不让它序列化为 json 字符串,而是作为任何有效的 JSON 结构未知?

object JsonObjectSerializer : KSerializer<JsonObject> {

    override val descriptor = PrimitiveSerialDescriptor("JsonObject", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): JsonObject =
        JsonObject(decoder.decodeString())

    override fun serialize(encoder: Encoder, value: JsonObject): Unit =
        encoder.encodeString(value.encode())
}

Out would be something like..出来会像..

{
    "some": "data",
    "jsonObject": "{\"this\": \"should not be a string\"}"
}

But wanted output would be..但想要 output 将是..

{
    "some": "data",
    "jsonObject": {"this": "should not be a string"}
}

encoder.encodeJsonElement might do what you want. encoder.encodeJsonElement可能会做你想做的事。

I use encodeJsonElement myself in the implementation of UnknownPolymorphicSerializer<P, W>我自己在UnknownPolymorphicSerializer<P, W>的实现中使用了encodeJsonElement

A serializer for polymorph objects of type [P] which wraps extending types unknown at runtime as instances of type [W]. [P] 类型的多态对象的序列化程序,它将运行时未知的扩展类型包装为 [W] 类型的实例。

I extract the known structure and wrap the the unknown structure.我提取已知结构并包装未知结构。 Maybe a similar use case than you are after?也许是一个与您所追求的类似的用例? The specifics, and use case, are fairly complicated, but documented in " UnknownPolymorphicSerializer: (De)serializing unknown types ".细节和用例相当复杂,但记录在“ UnknownPolymorphicSerializer: (De)serializing unknown types ”中。

@InternalSerializationApi
override fun serialize( encoder: Encoder, value: P )
{
    // This serializer assumes JSON serialization with class discriminator configured for polymorphism.
    // TODO: It should also be possible to support array polymorphism, but that is not a priority now.
    if ( encoder !is JsonEncoder )
    {
        throw unsupportedException
    }
    getClassDiscriminator( encoder.json ) // Throws error in case array polymorphism is used.

    // Get the unknown JSON object.
    check( value is UnknownPolymorphicWrapper )
    val unknown = Json.parseToJsonElement( value.jsonSource ) as JsonObject

    // HACK: Modify kotlinx.serialization internals to ensure the encoder is not in polymorphic mode.
    //  Otherwise, `encoder.encodeJsonElement` encodes type information, but this is already represented in the wrapped unknown object.
    AccessInternals.setField( encoder, "writePolymorphic", false )

    // Output the originally wrapped JSON.
    encoder.encodeJsonElement( unknown )
}

Ps AccessInternals is an expected implementation of mine to be able to use kotlin reflect, not supported on JS, since this is a multiplatform library. Ps AccessInternals是我的一个预期实现,能够使用 kotlin 反射,JS 不支持,因为这是一个多平台库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM