Преобразовать объект JsonFactory в строковое поле JSON в Kotlin - PullRequest
1 голос
/ 25 октября 2019

Посты, которые я видел, поменялись местами, но мне нужно создать строку JSON из объекта. Я новичок в Kotlin, но в JS я в основном ищу stringify.

Например:

JSON.stringify({foo: 'bar'})

Это то, что я хочу.

Я создал такой объект (который, если это не так, не нужнобыть построенным таким образом, я просто пытаюсь понять это)

    val factory = JsonFactory()
    val generator = factory.createGenerator(output, JsonEncoding.UTF8)

    generator.writeStartObject()
        generator.writeNumberField("statusCode", 200)

        generator.writeObjectFieldStart("body") // The value inside specifically needs to be a JSON string!
            generator.writeStringField("userId", user.id.toString())
            generator.writeStringField("amount", user.amount.toString())
            generator.writeStringField("percent", user.percent.toString())
        generator.writeEndObject()

    generator.writeEndObject()

    generator.close()

Это создаст объект как:

{"statusCode": 200, body: {userId: ..., amount: ..., percent: ...}}

Однако, это не будет работать (работа сLambda + API Gateway), а тело должно быть строковым блобом JSON, например:

{"statusCode": 200, body: "{\"userId\": ..., \"amount:\" ..., \"percent:\" ...}"}

Я просто не уверен, как это сделать. В настоящее время (так что я могу заставить что-то работать), я просто конкатюрирую в stringField вроде:

generator.writeStringField("body", "{" +

, который очень груб и сложен в управлении, поэтому я хотел бы сделать это "правильно"У меня такое чувство, что есть простой способ сделать это, но я не могу его найти.

1 Ответ

0 голосов
/ 25 октября 2019

kotlinx.serialization предоставляет решение для этого:

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

@UseExperimental(ImplicitReflectionSerializer::class)
fun main() {
    val json = Json(JsonConfiguration.Default)
    println(json.stringify(Response(status = 200,
            body = json.stringify(Payment("abc", 100, 20)))))
}

@Serializable
data class Payment(val userId: String, val amount: Int, val percent: Int)

@Serializable
data class Response(val status: Int, val body: String)

Но допустим, вы не можете использовать kotlinx.serialization, так как это экспериментально.

Вы по-прежнему можете использовать ObjectMapper из jackson библиотеки (как я вижу, вы используете их JsonFactory, что является низким уровнем):

import com.fasterxml.jackson.databind.ObjectMapper

fun main() {
    val json = ObjectMapper()

    println(json.writeValueAsString(Response(status = 200,
            body = json.writeValueAsString(Payment("abc", 100, 20)))))
}

data class Payment(val userId: String, val amount: Int, val percent: Int)

data class Response(val status: Int, val body: String)

Вы можете даже иметьсвой JSON.stringify:

object JSON {
    fun stringify(e: Any) = ObjectMapper().writeValueAsString(e)
}

Или используйте его как функцию расширения:

fun main() {
    println(Response(status = 200,
            body = Payment("abc", 100, 20).asJson().toString()).asJson())
}

data class Payment(val userId: String, val amount: Int, val percent: Int)

data class Response(val status: Int, val body: String)

fun Any.asJson() = ObjectMapper().writeValueAsString(this)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...