2

我有以下对象,我使用 Circe 将其序列化为 json

case class Person(name: String, data: String)
val x = Person("test", s"""{"a": 10, "b":"foo"}""")
import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
println(x.asJson)

上面语句的输出是

{
  "name" : "test",
  "data" : "{\"a\":10, \"b\":\"foo\"}"
}

但我想要的输出是

{
    "name": "test",
    "data": {
        "a": 10,
        "b": "foo"
    }
}

我从基于 json 的数据存储中获取数据字段的数据。我想通过它(所以我不想将它解组为 scala 对象,只是将其重新编组为 json。编组/解组是我服务器上 CPU 的浪费。

那么我该如何处理这些数据呢?

4

1 回答 1

3

好吧,您可以编写自己的Encoder实现,例如:

import io.circe.{Encoder, Json}
import io.circe.jawn.parse

case class Person(name: String, data: String)

implicit val personEncoder: Encoder[Person] = new Encoder[Person] {
  override def apply(person: Person): Json = {
    val name = Json.fromString(person.name)
    val data = parse(person.data) match {
      case Left(_)      => Json.obj()
      case Right(value) => value
    }
    Json.obj("name" -> name, "data" -> data)
  }
}

事实上,您遇到了非常不寻常的情况 - 其中一个字段是 a String,您需要在将其作为子 Json 节点之前对其进行解析。错误失败需要以某种方式处理 - 我使用了空对象,但这不一定是您想要使用的。

如果你想省略反序列化步骤......那是不可能的。您正在构建具有已定义行为的 JSON 节点树。字符串不能突然被视为Json对象。

于 2017-04-11T20:20:48.407 回答