Json 序列化中的跳过键

Skip key in Json serialization

我有以下案例class规范

case class A(messages: Vector[SomeClass])

我想避免出现如下序列化结果:

{ 
    "messages":[{...},{...}]
}

我想跳过 JsonObject 规范,直接序列化内容。所以结果看起来像:

[
    {
        "key":"a"
    },
    {
        "key":"b"
    }
]

我试过像下面这样指定一个隐式转换器

object A {
    implicit val writes:[Writes] = (o: A) => JsArray(o.messages.map(Json.toJson(_)))
    // also tried this Json.arr(o.messages.map(Json.toJson(_))) which has the same result 
}

但这会在数组中生成一个数组

[
    [
        {
            "key":"a"
        },
        {
            "key":"b"
        }
    ]
]

SomeClass 是一个密封的特征,它的扩展被正确地序列化和反序列化。我的问题是 case class A 的数组嵌套。有什么想法吗?

您可以使用 Writes.contramap and Reads.map, with Writes.seq and Reads.seq

import play.api.libs.json._

case class SomeClass(foo: String)

implicit val format1: OFormat[SomeClass] = Json.format

case class A(messages: Vector[SomeClass])

// Writes
implicit def writes(implicit w: OWrites[SomeClass]): Writes[A] =
  Writes.seq[SomeClass].contramap[A](_.messages)

Json.toJson(A(Vector(SomeClass("bar"))))
// play.api.libs.json.JsValue = [{"foo":"bar"}]

// Reads
implicit def reads(implicit r: Reads[SomeClass]): Reads[A] =
  Reads.seq[SomeClass].map { seq => A(seq.toVector) }

Json.parse("""[{"foo":"bar"}]""").validate[A]
// play.api.libs.json.JsResult[A] = JsSuccess(A(Vector(SomeClass(bar))),)

先用 case class 提取 Vector

import play.api.libs.json._

val a: A = ???
Json.toJson(a.messages)

您需要的是 SomeClass:

的格式
object SomeClass {
  implicit val jsonFormat: Format[SomeClass] = Json.format[SomeClass]
}