use*_*343 4 json scala playframework
我有以下案例类:
case class Test(name: String, email: String, phone: String)
Run Code Online (Sandbox Code Playgroud)
所以为了能够序列化到JSON,我写道:
implicit val testWrites: Writes[Test] = (
(__ \ "name").write[String] and
(__ \ "email").write[String] and
(__ \ "phone").write[String]
)(unlift(Test.unapply))
Run Code Online (Sandbox Code Playgroud)
我想将它用作DTO对象之类的东西,所以我可以在serizalizing时排除一些字段.我们说我想只显示name和email字段.
我试过这样的事情:
implicit val testWrites: Writes[Test] = (
(__ \ "name").write[String] and
(__ \ "email").write[String]
)(unlift(Test.unapply))
Run Code Online (Sandbox Code Playgroud)
但是这给了我编译错误 - > Application does not take parameters.
有谁知道问题是什么,以及我如何实现上述想法?
Mic*_*jac 12
播放JSON组合器通常会利用unapply在案例类的伴随对象中自动生成的方法.
对于您的案例类:
case class Test(name: String, email: String, phone: String)
Run Code Online (Sandbox Code Playgroud)
unapply方法如下所示:
def unapply(test: Test): Option[(String, String, String)] = Some((test.name, test.email, test.phone))
Run Code Online (Sandbox Code Playgroud)
它返回包含并包装的case类的字段值Option.例如:
val test: Test = Test("John Sample", "fake@email.com", "1-800-NOT-NULL")
Test.unapply(test) // returns Some(("John Sample", "fake@email.com", "1-800-NOT-NULL"))
Run Code Online (Sandbox Code Playgroud)
unlift将unapply函数转换为a PartialFunction[Test, (String, String, String)],然后将其用于映射Test元组的实例,然后将其用于序列化类.
你不需要使用Test.unapply.当您想要序列化整个类时,它只是方便使用它.如果您只想要一些字段,则可以定义类似的功能Test => Option[(String, String)]:
def simpleExtractor(test: Test): Option[(String, String)] = Some(test.name, test.email)
Run Code Online (Sandbox Code Playgroud)
然后在JSON组合器中使用它:
implicit val testWrites: Writes[Test] = (
(__ \ "name").write[String] and
(__ \ "email").write[String]
)(unlift(simpleExtractor))
Run Code Online (Sandbox Code Playgroud)
同样,JSON Reads经常利用自动生成apply的case类方法.Test.apply _是一个函数(String, String, String) => Test- 基本上与unapply您可能已经猜到的相反.JSON API使用在其中指定的字段组装一个元组Reads,然后传递该元组Test.apply _,从而生成反序列化的元组Test.
要生成一个Reads只读取两个字段,您可以定义另一个类似应用的函数:
def simpleBuilder(name: String, email: String): Test = Test(name, email, "default")
implicit val testReads: Reads[Test] = (
(__ \ "name").read[String] and
(__ \ "email").read[String]
)(unlift(simpleBuilder _))
Run Code Online (Sandbox Code Playgroud)
虽然我个人不喜欢这样做,并在Reads自己内部定义一个默认值:
implicit val testReads: Reads[Test] = (
(__ \ "name").read[String] and
(__ \ "email").read[String] and
(__ \ "phone").read[String].orElse(Reads.pure("default"))
)(unlift(Test.apply _))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1488 次 |
| 最近记录: |