所以我的项目中有两个课程
case class Item(id: Int, name: String)
和
case class Order(id: Int, items: List[Item])
我正在尝试为Order创建读写属性,但我收到编译错误:
“找不到unapply或unapplySeq函数”
在我的控制器中,我有以下内容:
implicit val itemReads = Json.reads[Item]
implicit val itemWrites = Json.writes[Item]
implicit val listItemReads = Json.reads[List[Item]]
implicit val listItemWrites = Json.writes[List[Item]]
该代码适用于itemReads
和itemWrites
,但不适用于底部两个。谁能告诉我哪里出错了,我是Play框架的新手。
感谢您的时间。
答案 0 :(得分:6)
你实际上并不需要定义这两个含义,游戏已经知道如何处理列表:
scala> import play.api.libs.json._
import play.api.libs.json._
scala> case class Item(id: Int, name: String)
defined class Item
scala> case class Order(id: Int, items: List[Item])
defined class Order
scala> implicit val itemReads = Json.reads[Item]
itemReads: play.api.libs.json.Reads[Item] = play.api.libs.json.Reads$$anon$8@478fdbc9
scala> implicit val itemWrites = Json.writes[Item]
itemWrites: play.api.libs.json.OWrites[Item] = play.api.libs.json.OWrites$$anon$2@26de09b8
scala> Json.toJson(List(Item(1, ""), Item(2, "")))
res0: play.api.libs.json.JsValue = [{"id":1,"name":""},{"id":2,"name":""}]
scala> Json.toJson(Order(10, List(Item(1, ""), Item(2, ""))))
res1: play.api.libs.json.JsValue = {"id":10,"items":[{"id":1,"name":""},{"id":2,"name":""}]}
您看到的错误可能是因为Play使用unapply方法为您的读/写构造宏扩展而List
是一个抽象类,play-json需要具体类型才能使宏工作。
答案 1 :(得分:6)
" No unapply or unapplySeq function found
"错误是由这两个引起的:
implicit val listItemReads = Json.reads[List[Item]]
implicit val listItemWrites = Json.writes[List[Item]]
把它们扔掉。 As Ende said,Play知道如何处理列表。
但是Reads
也需要Writes
和Order
!既然你同时阅读和写作,最简单的方法是定义Format
,Reads
和Writes
特征的混合。这应该有效:
case class Item(id: Int, name: String)
object Item {
implicit val format = Json.format[Item]
}
case class Order(id: Int, items: List[Item])
object Order {
implicit val format = Json.format[Order]
}
上面,ordering is significant; Item
和伴随对象必须在Order
之前。
因此,一旦你需要所有隐式转换器,关键是使它们在控制器中正确显示。以上是一种解决方案,但还有其他方法,正如我在trying to do something similar之后学到的那样。
答案 2 :(得分:1)
这有效:
case class Item(id: Int, name: String)
case class Order(id: Int, items: List[Item])
implicit val itemFormat = Json.format[Item]
implicit val orderFormat: Format[Order] = (
(JsPath \ "id").format[Int] and
(JsPath \ "items").format[JsArray].inmap(
(v: JsArray) => v.value.map(v => v.as[Item]).toList,
(l: List[Item]) => JsArray(l.map(item => Json.toJson(item)))
)
)(Order.apply, unlift(Order.unapply))
这也允许您自定义JSON对象的命名。以下是序列化的实例。
Json.toJson(Order(1, List(Item(2, "Item 2"))))
res0: play.api.libs.json.JsValue = {"id":1,"items":[{"id":2,"name":"Item 2"}]}
Json.parse(
"""
|{"id":1,"items":[{"id":2,"name":"Item 2"}]}
""".stripMargin).as[Order]
res1: Order = Order(1,List(Item(2,Item 2)))
如果您正在进行对称序列化/反序列化,我还建议您使用format
代替read
和write
。