簡體   English   中英

在 kotlinx.serialization 中編碼/解碼 JSON “字符串”

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

是否可以在自定義序列化程序中以字符串格式對任何有效的 json 對象進行編碼/解碼。 例如下面的代碼,但不讓它序列化為 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())
}

出來會像..

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

但想要 output 將是..

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

encoder.encodeJsonElement可能會做你想做的事。

我自己在UnknownPolymorphicSerializer<P, W>的實現中使用了encodeJsonElement

[P] 類型的多態對象的序列化程序,它將運行時未知的擴展類型包裝為 [W] 類型的實例。

我提取已知結構並包裝未知結構。 也許是一個與您所追求的類似的用例? 細節和用例相當復雜,但記錄在“ 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是我的一個預期實現,能夠使用 kotlin 反射,JS 不支持,因為這是一個多平台庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM