我有以下案例类说明
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
是密封特性,其扩展名已正确序列化和反序列化。我的问题是案例类A
的数组嵌套。有什么想法吗?
您可以将Writes.contramap
和Writes.contramap
与Reads.map
和Reads.map
一起使用。
Writes.seq
只需先用Writes.seq
提取Vector:
Reads.seq
您需要的是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))),)